1. Advertising
    y u no do it?

    Advertising (learn more)

    Advertise virtually anything here, with CPM banner ads, CPM email ads and CPC contextual links. You can target relevant areas of the site and show ads based on geographical location of the user if you wish.

    Starts at just $1 per CPM or $0.10 per CPC.

DB classes with OOP (rewriting code), best solution?

Discussion in 'PHP' started by iago111, Jun 21, 2020.

  1. #1
    Hi guys,
    I'm about to rewriting code using OOP.
    I started with the db connection (PDO).
    SEMrush
    I turned this:
    $dsn_test = "mysql:host=localhost;dbname=xxx50;charset=utf8mb4";
    $options = [
      PDO::ATTR_EMULATE_PREPARES   => false, // turn off emulation mode for "real" prepared statements
      PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION, //turn on errors in the form of exceptions
      PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, //make the default fetch be an associative array
    ];
    try {
      $pdo = new PDO($dsn_test, "root", "", $options);
    } catch (Exception $e) {
      error_log($e->getMessage());
      exit('db error');
    }
    PHP:
    into this:
    class Database {
    
      private $host = 'localhost';
      private $user = 'root';
      private $pass = '';
      private $dbname = 'xxx50';
    
      public $dbh;
      public $error;
    
      public function __construct()  {
    
        $dsn = 'mysql:host='.$this->host.';dbname='.$this->dbname.';charset=utf8mb4';
    
        $options = [
          PDO::ATTR_EMULATE_PREPARES   => false, // turn off emulation mode for "real" prepared statements
          PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION, //turn on errors in the form of exceptions
          PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, //make the default fetch be an associative array
    ];
    
        try {
            $this->dbh = new PDO($dsn,$this->user,$this->pass, $options);
    
          }
       
          catch (PDOException $e) {
             $this->error = $e->getMessage();
    
          }
      }
    }
    PHP:
    Starting programming with JAVA(TM) I'm used to use a contructor. Does that make sense here?
    How can I ensure that the db connection will be closed after closing the site?

    After watching 100+ tutorials, I still don't know where to store the data for the connection?
    If I pass the data when I instantiate the object, is this more secure than the solution above??
     
    Solved! View solution.
    iago111, Jun 21, 2020 IP
    SEMrush
  2. #2
    I would put ALL the data in the constructor NOT as variables, but in the call to the New PDO. Variables for nothing in an INTERPRETED language -- even private (See "include scope bleed") -- can eventually bite you in the ass and has a performance hit.

    I'd also likely just extend PDO rather than making a from scratch new class... and lands sake, just build the DSN... and really set the encoding on the table, not the connection.

    
    class Database extends PDO {
    
    	public function __construct() {
    		parent::__construct(
    			'mysql:host=localhost;dbname=xxx50',
    			'root', // username
    			'', // password
    			[
    				PDO::ATTR_EMULATE_PREPARES   => false, prepared statements
    				PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    				PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
    			]
    		);
    	}
    
    }
    Code (markup):
    Drive-by coding, may be typo's

    I'd then still explicitly do the try/catch when connecting.

    Though honestly I wouldn't even do that in actual production code. These days I'd put it in my "one index.php to rule them all" as a normal PDO connection in a IIFE so the connection isn't in global scope and can't just be called from anywhere, and then only pass the variable holding the connection to code that NEEDS it. That way you only have a single entry vector to guard, you're unlikely to bleed the connection data or the connection to code elevations/hacks, and reduce the damage that can be done WHEN a mistake elsewhere bites you.
     
    deathshadow, Jun 21, 2020 IP
    sarahk likes this.
  3. iago111

    iago111 Peon

    Messages:
    26
    Likes Received:
    1
    Best Answers:
    0
    Trophy Points:
    3
    #3
    I thought IIFE is connected to JS pimarily??.. Additionally to the index.php, I also have an actions.php, where I handle all the AJAX requests, so I need a PDO connection there, too.

    ##And login.php, I forgot that!!
     
    Last edited: Jun 23, 2020
    iago111, Jun 23, 2020 IP
  4. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,305
    Likes Received:
    1,806
    Best Answers:
    244
    Trophy Points:
    515
    #4
    They were added in PHP 7, and provide a great way for your index.php to not accidentally bleed scope should a "code appendage" occur. Sometimes rather than figure out all your code it's just easier for crackers to slap their code at the end of your own. If you put your connection in a IIFE and only pass it to functions, you basically remove that avenue of attack from having database access.

    It's the same reason I use this dumbass idiotic code to break scope:

    function safeInclude(fileName) { include(fileName); }
    Code (markup):
    That way my current scope doesn't bleed into the include.

    test.php
    
    <?php
    function test() {
      $a = 10;
      include('access.php');
    }
    Code (markup):
    access.php
    
    <?php
    echo $a;
    
    Code (markup):
    Will output 10, PHP treats includes as literals and provides no scope isolating library mechanism. You swap include for my "safeInclue" it will throw an error because $a isn't defined in safeInclude's scope.

    ... and I advise against doing that. If you have one single index.php that ALL user calls are routed through, you have only "one gate to guard". It means you only need to store the database connection data in one place reducing the odds of attackers gaining access to it.

    My typical index.php goes a little something like this these days (paraphrasing)

    
    <?php
    
    (function() {
    
    	/*
    		If we set up compression FIRST via buffering first, we can
    		header/cookie/session across the whole output with impunity
    	*/
    
    	foreach (['gzip', 'x-gzip', 'x-compress'] as $type) {
    		if (strpos($_SERVER['HTTP_ACCEPT_ENCODING'], $type) !== false) {
    			define('CONTENT_ENCODING', $type);
    			ob_start('ob_gzhandler');
    			ob_implicit_flush(0);
    			register_shutdown_function(function() { 
    				header('Content-Encoding: ' . CONTENT_ENCODING);
    				ob_end_flush();
    			});
    			break;
    		}
    	}
    	
    	// prevent displaying site in frame
    	header('X-Frame-Options: DENY');
    	
    	/*
    		Always regenerate the id to reduce the window in which MITM
    		attacks can occur
    	*/
    	session_start();
    	session_regenerate_id();
    	
    	/*
    		functions and objecs used across all calls. This includes things
    		like safeInclude and the User object.
    	*/
    	include(libs/common.lib.php);
    	
    	/*
    		In practice I have an extended PDO for "named queries"
    		and multi-engine support.
    	*/
    	$db = new PDO(
    		'mysql:host=localhost;dbname=paladinCMS',
    		'username',
    		'password',
    		[
    			PDO::ATTR_EMULATE_PREPARES   => false, prepared statements
    			PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    			PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
    		]
    	);
    	
    	// User object is in common.lib.php
    	$user = new User($db);
    	
    	/*
    		$user->id is the preferred way of accessing the current user, 
    		but a copy exists in $_SESSION['user']['id'] as a backup. 
    
    		Note $user->id is preferred as it's handled via a __get magic method
    		so the value	cannot be changed from "outside" the User object.
    		
    		Common user ID's:
    		
    			negative values can't be in DB making easy way to check
    			logged in as ($user->id >= 0)
    			
    			-1 : "Guest", easy to check login state
    			-2 : "Banned"
    			
    		$user->errors : associative array, reports login errors
    	*/
    	
    	safeInclude('dispatch/' . (
    		$user->id == -2 ? 'banned' : (
    			!empty($_GET['ajax']) ? 'ajax' : 'html'
    		)
    	) . '.dispatch.php');
    	
    	// dispatcher function is from appropriate include above.
    	dispatcher($db, $user);
    	
    })();
    Code (markup):
    One gateway to guard. All requests are routed through it so I can control what does and does not get access to $db. Includes typically have conditions behind them so I can control whether or not code that isn't going to be used/run isn't actually included.

    ... and remember one of the most basic lessons of PHP. None of your 'include' should EVER be allowed to output anything or run anything directly. ALL of your include should -- whenever possible -- contain nothing but Object classes and Functions that the code including it needs to explicitly call. This way should any of those sub PHP files get called directly via URI they do nothing.

    Typically I combine the above technique with this httpd.conf / .htaccess rule:

    RewriteEngine On
    RewriteRule !(^(images|downloads))|(\.(gif|jpg|png|webp|css|js|html|txt|ico|zip|rar|pdf|xml|mp3|mp4|mpg|flv|swf|mkv|ogg|avi|woff|woff2|svg|eot|ttf|test|json)$) index.php
    
    Code (markup):
    A whitelist of file types to allow normal access to. Any AND ALL other requests are routed to the index.php. This:

    1) prevents even being able to call .php files from the URI, for an added measure of protection

    2) makes adding custom error handlers (404 for example) easy since you can even use the same template as the rest of the site on the fly

    3) Allows us to make "friendly URI's" (people call it "search friendly", that's not who it's for!) by simply parsing the contents of $_SERVER['REQUEST_URI']. In my common.lib.php I typically have a "Request" static object / faux singleton that handles said parsing. This way .htaccess isn't wasting time trying to regex parse our directory names into the URI query ($_GET) interfering with or breaking the ability to even use "get data" from the client side... a weakness found in more conventional approaches to "Friendly URI" handling.
     
    deathshadow, Jun 26, 2020 IP
  5. iago111

    iago111 Peon

    Messages:
    26
    Likes Received:
    1
    Best Answers:
    0
    Trophy Points:
    3
    #5
    Ok, thanks for the index.php, takes a time to get through that!! :cool:
     
    iago111, Jun 28, 2020 IP
  6. JEET

    JEET Notable Member

    Messages:
    3,304
    Likes Received:
    351
    Best Answers:
    15
    Trophy Points:
    235
    #6
    @deathshadow

    Suppose a hacker is able to insert a code at the bottom of your index.php
    That would mean that they have found access to your pdo class as well.
    If your connection variables are hard coded in that file, then they just have to call the constructor, and they have access to database...

    Plus, I think that only way to actually put a code at the bottom of a file is to have ftp access,
    or to have a faulty form where submit writes to a "relative" path writeable file.
    Something like this:

    <form>
    <input type="text" name="chatID" value="xxx" />
    <input type="text" name="t" value="" />
    <input type="submit" value="Post" />
    </form>

    Then on submit page:
    $t= $_REQUEST['t'];
    //this is the problem line below
    $file= "chatFolder/" . $_REQUEST['chatID'];
    //php code to append to file
    $fp= fopen($file, 'a'); fwrite($fp, "$t\n"); fclose($fp);

    Somebody from an outside form can post this to this submit script:
    <form>
    <input type="text" name="chatID" value="../index.php<" />
    <input type="text" name="t" value="Some malicious code here" />
    <input type="submit" value="Post" />
    </form>

    So the above submit code becomes:
    $file = "chatFolder/". "../index.php";
    $fp= fopen($file, 'a'); fwrite($fp, "$t\n"); fclose($fp);


    Other than this I can only think of someone gaining FTP access to append something to one of the files on the server...
    Or is there some other way too?

    If something happens at server level, like compromised ftp access, then it will not matter how strongly the script is coded or how private or global its variables are.
    Hackers got full access anyways...

    Suppose I got a global variable in my script.
    Then how can someone else access it, unless they got their code in my file?
    And if they got their code in my file, then it won't matter if variable is global or function private. They can call the function...
     
    JEET, Jun 28, 2020 IP
  7. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,305
    Likes Received:
    1,806
    Best Answers:
    244
    Trophy Points:
    515
    #7
    NO, they wouldn't. Because $db is local to the anonymous IIFE. As that function has no name, nothing inside it exists in the global scope. They'd have to remove the })(); and supply their own, which is often "more effort" than most code appendage cracks are willing to put in.

    Of course one good fopen/file_get_contents and ALL well laid plans for PHP security get shoved up one's well laid ass, but that's why in ultra-secure environments you actually block ALL file operations.

    Again that stupid idioitic problem with PHP that could be solved if PHP simply didn't allow source code to be read/written to, only included. A simple if statement checking the extension, something like ".phpSecure", and throwing an error if anything other than include/require tries to access it. Around two thirds of all PHP hacks/cracks/exploits would fall flat on their face if that mechanism were implemented... but last time I suggested it I got told to STFU.

    It's almost like they WANT it to be insecure "by design".

    Remember, PHP can fopen ANY PHP file it can execute or include, and write to it if it's not 444. (which is oft impractical) so if you have a code elevation injecting code at the end of anything is easy-peasy lemon-squeezy.

    It's also why I shudder in horror when I see directories and files set to 755, even when it's a necessary evil.
     
    Last edited: Jun 28, 2020
    deathshadow, Jun 28, 2020 IP
    JEET likes this.
  8. JEET

    JEET Notable Member

    Messages:
    3,304
    Likes Received:
    351
    Best Answers:
    15
    Trophy Points:
    235
    #8
    @deathshadow
    Solution to PHP writing to PHP files is really simple.
    The coder simply has to add an extension to the $file, like in the code above:

    $file= "chatFolder/". $_POST['id']. ".txt";
    Its still a useless code, but better than the code in my earlier comment.
    This way at least ".php" files will not get overwritten or appended to.
    Somebody posts "../index.php", and it becomes "chatFolder/../index.php.txt"

    By the way, I still don't understand the PDO non-global system you are trying to explain.
    You will still need to make database connection and store that in a global variable "$link", so that you can use this $link later to send a query, isn't it?

    $link = new DATABASE();
    $r = $link->myQuery(" select etc etc ");

    If this is the case, then $link is a global scope variable, available to all other code in the script later...

    Can you please show an example how query is sent using the DATABASE class above?
    Thanks
     
    JEET, Jun 28, 2020 IP
  9. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,305
    Likes Received:
    1,806
    Best Answers:
    244
    Trophy Points:
    515
    #9
    It's really simple. $db -- the PDO connection -- in that index.php I showed is NOT in global scope. That function passes it to User when it's constructed for the main user, and to the dispatcher so it too can pass it where it NEEDS to go, without it being everywhere in the code. There's no reason for it to exist in the scope of the template, or library functions, or User after it's constructed for example, so don't pass it as a parameter to those things. Just as safeInclude breaks scope so that $db (or $link if you prefer) won't exist in it's execution scope, only in functions inside it IF you pass it to them.

    That way the number of places it can be exploited is reduced. It's by no means a full protection, but it's one of the many rings of protection you can set up to make you a harder target.

    Let's simplify it down to the basics:

    Index.php
    
    <?php
    function safeInclude(fileName) { include(fileName) };
    
    (function() {
      $link = 'dummy value';
      include('test1.inc.php');
      safeInclude('test2.inc.php');
    })();
    
    Code (markup):
    test.inc.php
    
    <?php
    echo '
    	$link ', (
    		isset($link) ? 'existed' : 'did not exist'
    	), ' in global scope<br>';
    
    Code (markup):
    When "include" is run it exists, when safeInclude is run it does not because safeInclude broke scope.

    This means the only way to pass $link to the include is to pass it to a function/constructor/method.

    Hence:

    $user = new User($db);

    passes $db, my pdo link, to User's constructor. Just as:

    dispatcher($db, $user);
    Code (markup):
    Passes both $db and $user so they in turn can be stored or used as needed in whatever it calls. Only pass it where it's needed, instead of slopping it into global scope. It's one of the reasons mysqli and PDO have object handles in the first place, unlike the derpy mysqli_ "connection is global by default" approach. It's the whole reason that said handler (or "link" if you prefer) mechanism EXISTS.

    It's a bit like always regenerating the session ID on every request, in that it doesn't prevent MITM attacks, it just narrows the time window in which one can occur. In that same way this doesn't make you rock solid secure, it just reduces the number of places in the code where this information is made available.

    Multi-ring security. Single entry point, scope isolation, database isolation, separation of concerns, linear execution flow to reduce complexity... You end up with a ring castle as opposed to having 500 entrances and the keys dangling unguarded in the central courtyard.

    There's an old joke, "the only secure system is one with zero access. From there it's all nonsense." In that way I consider application security to be a bit like home security, which is only effective for one thing, intimidation. You can have the most advanced security on the planet, but if a professional REALLY wants to break in there's generally jack-all you can do about it... but if you neighbor is a softer target with a high payout, they'll be robbed before you are.

    Kind of like doorlocks on a car. A professional can slim-jim it in a heartbeat. A brick can go through your windows. You still lock the doors.

    Or "anti-mask wearing" logic. If seatbelts work why the airbags? If both systems work, why bother having brakes?

    LAYERED security. None of it's infallible, in fact most of it is more smoke and mirrors than fact... but if you've ever been through a carnival funhouse, you know smoke and mirrors can be shockingly effective. It's not about making yourself invulnerable, there's NO SUCH THING. Especially with PHP... It's about making yourself a harder target than the next poor schlub. Criminals by nature are lazy, and looking for "soft targets" that provide the most payout for the least risk and effort.

    Hence why the most effective Crim's aren't the ones running around knocking over convenience stores. They're the snake oil peddlers and white collar criminals who go around looking for the easy marks.
     
    deathshadow, Jun 29, 2020 IP
    JEET likes this.
  10. JEET

    JEET Notable Member

    Messages:
    3,304
    Likes Received:
    351
    Best Answers:
    15
    Trophy Points:
    235
    #10
    @deathshadow
    Here is a code, how would you rewrite it for security?
    I would really like to learn more from you on this subject.


    This code below gets pageName from queryString, selects page data from table, displays page.
    Then second query gets some more pages, recently created ones, and shows links to those

    index.php
    <?php
    $db = new mysqli( etc etc );

    $page= addslashes($_GET['page']);

    $r= $db->query("select * from pageTable where pageName='$page' limit 1 );
    //show page data here


    //show links to some additional pages
    $r= $db->query(" select pageName, pageTitle from pageTable order by createdTime desc limit 5 ");
    //show 5 links here

    ?>
     
    JEET, Jun 29, 2020 IP
  11. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,305
    Likes Received:
    1,806
    Best Answers:
    244
    Trophy Points:
    515
    #11
    Well, first off lose the closing ?>, it really serves little purpose. Next why are you dicking around with addslashes, and what makes you think getData belongs in your query string? It's called prepare/execute, USE IT. Otherwise you might as well go back to using mysql_ functions PHP 5 style. Something were were SUPPOSED to stop doing way back in 2006.

    Even with the derpy mysqli the ->query method is the wrong one if you're putting variables into it!

    I'd also just call it "pages", as "pageTable" seems a little redundant for a mysql table.

    <?php
    
    */
    	load the common template first so we don't have scope
    	passing issues.
    */
    include('template/common.template.php');
    
    // safeInclude breaks scope on include
    function safeInclude($filename) { include($fileName); }
    
    (function() {
    
    	$db = new PDO(
    		'mysql:host=localhost;dbname=test',
    		'username',
    		'password',
    		[
    			PDO::ATTR_EMULATE_PREPARES => false,
    			PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    			PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
    		]
    	);
    	
    	// load page unique template stuff
    	safeInclude('template/pages.template.php');
    	
    	$stmt = $db->prepare('
    		SELECT *
    		FROM pages
    		WHERE pageName = ?
    		LIMIT 1
    	');
    	$stmt->execute([$_GET['page']]);
    	
    	if ($page = $stmt->fetch()) {
    		/*
    			My template_header() (common.template.php) outputs everything
    			from  <!DOCTYPE html> to the <main> tag or wherever your page's
    			unique content starts.
    		*/
    		template_header('page title');
    		template_page($page);
    	} else {
    		header('HTTP/1.0 404 Not Found');
    		template_header('404 Not Found');
    		template_pages_notFound(htmlspecialchars($_GET['page']));
    	}
    	
    	$stmt = $db->query('
    		SELECT pageName, pageTitle
    		FROM pages
    		ORDER BY createdTime DESC
    		LIMIT 5
    	');
    	
    	template_pages_summaryHeader();
    	while ($row = $stmt->fetch()) template_pages_summaryRow($row);
    	template_pages_summaryFooter();
    	
    	/*
    		template_footer, also from common.template.php spits out
    		everything from </main> or whatever your content wrapper is,
    		to </html>.
    	*/
    	template_footer(); // everything after </main>
    	
    })();
    Code (markup):
    Notice the extra handler for if there's a miss. My template_pages_notFound() would likely send a 404 header. Again separation of concerns in that whilst we CALL the template functions, anything that actually outputs markup is not in our logic. If you "echo" or ?>Some code<?php , or even <?=something?> in the middle of your database and processing logic, you're doing something wrong. Keep that crap in the template.

    Thankfully PHP is and of itself a template system, which is why the dipshit practice of running template systems like Smarty atop PHP is so dipshit...
     
    deathshadow, Jun 29, 2020 IP
    JEET likes this.
  12. JEET

    JEET Notable Member

    Messages:
    3,304
    Likes Received:
    351
    Best Answers:
    15
    Trophy Points:
    235
    #12
    JEET, Jun 30, 2020 IP
  13. SpacePhoenix

    SpacePhoenix Well-Known Member

    Messages:
    148
    Likes Received:
    19
    Best Answers:
    2
    Trophy Points:
    120
    #13
    @deathshadow as a side note, what's your thoughts on type casting combined with the use of strict types mode?
     
    SpacePhoenix, Jun 30, 2020 IP
  14. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,305
    Likes Received:
    1,806
    Best Answers:
    244
    Trophy Points:
    515
    #14
    I SHOULD like it, coming from a Pasca/Modula2/Ada background, but there's just something off about it. Kind of like how I SHOULD like python for its strict use of whitespace, but find it fragile and to in fact be one of the more difficult languages out there to work with... or typescript which just vomits up bloated trash code.

    They all try to turn the parent language into something it's not, and as a result mollycoddles people's bad practices instead of having people embrace the underlying language for what it is. There's a "reek" of shoe-horning in concepts from other languages where they just don't fit to it all.

    I also find it obtuse and outright stupid that it doesn't apply across all files once set, so you have to manually declare strict types in every blasted include... when include are SUPPOSED to just be treated as if the code is right there. They can put all the effort into doing that, but they STILL can't give us an include type that is scope breaking and cannot be fopen/file_get_contents? It's a bunch of wasted effort they put into one spot, that could have been better spent fixing the gaping security holes in the language.

    Much like Mozilla bragging about Firefox's HTML 5 "support" (aka treat it as a bunch of DIV, wow, that's useful -- not) a little over a decade ago when they didn't even have HTML 4 support complete and to this day have 20 year old bugs... That they've now labeled as "won't fix, don't care". (see the infamous Bugzilla 915)

    It's a problem we see a lot in web development, in that long standing bugs and issues never get fixed, but some new-fangled complicated but flashy nonsense gets all the attention.

    The shoe-horning of strict typecasting into PHP also just feels like people who want it to behave like some other programming language, in which case why not just use that language instead of PHP? Same as what's happening in ECMAScript where it's getting pissed on with bad concepts and practices from other languages, a painful increase in how cryptic the syntax is, for negligible benefit and much of it reeking of "Look, just go back to C#, VB, Java, or whatever language you came from."

    I actually made the same mistake 25 years ago when I moved from Wirth family languages to C and C++. I kept trying to make them behave like Ada, instead of embracing the differences. I see that same mistake being made now with languages like PHP and JavaScript ... and even HTML... Where all this extra junk is being added, when to be frank the OPPOSITE should be being done.

    As I oft say about many other things, they're not simpler, or easier, or better, no matter how many people mindlessly parrot the propaganda.

    Don't get me wrong, there's a LOT of genuine improvements in PHP for people to embrace, but this pathetic attempt at adding strict typecasting isn't it. Anymore than the disaster that is typescript is an actual improvement over vanilla JS. At least client-side. I'll admit I don't do enough node.js server-side to say for certain there.

    ... and before some numb-nuts goes "what's JS got to do with it, wah wah OT" it's called similies. Supporting comparisons. and no, I didn't just misspell smilie.
     
    deathshadow, Jul 1, 2020 IP
    JEET likes this.
  15. JEET

    JEET Notable Member

    Messages:
    3,304
    Likes Received:
    351
    Best Answers:
    15
    Trophy Points:
    235
    #15
    @deathshadow
    You mentioned in your earlier comment, to my request,
    not to use addslashes.
    Are you talking about using filters instead? FILTER_SANITIZE_MAGIC_QUOTES...
    Isn't this doing the same as addslashes?
     
    JEET, Jul 1, 2020 IP
  16. deathshadow

    deathshadow Acclaimed Member

    Messages:
    9,305
    Likes Received:
    1,806
    Best Answers:
    244
    Trophy Points:
    515
    #16
    You shouldn't be doing anything that needs that type of rubbish anymore. Your get/post data shouldn't be screwed with since magic_quotes have been disabled by default since PHP 5.2 (I think, may have been a little later), and any sanitation needs would/should be served by the separation of query from execution provided by prepare/execute.

    Dicking around with slashes from user input is 15 year out of date nonsense in all but a handful of corner cases... such as when working with LIKE. If you use Prepare/execute -- one of the entire reasons mysql_ went away in the first place, you don't need extra escape sequences or sanitation to plug values into your query strings. It's handled for you.

    Hence why any time after around 2006, slopping variables into your query strings is bloated, insecure, outmoded trash.

    Thus this:
    
    $page= addslashes($_GET['page']);
    $r= $db->query("select * from pageTable where pageName='$page' limit 1 );
    
    Code (markup):
    Is outmoded, outdated, nonsensical 2006/earlier approach. Anyone telling you to build a query that way needing a quadruple helping of Sierra Tango Foxtrot Uniform.

    It should be done as this: (if PDO)
    
    $stmt = $db->prepare('SELECT * FROM pageTable WHERE pageName = ? LIMIT 1');
    $stmt->execute([$_GET['page']]);
    
    Code (markup):
    The array values of the execute are sanitized/escaped for you, and are much more guaranteed to be secured because if emulated prepares are off, they're sent SEPARATELY from the query entirely.

    mysqli is a bit trickier, which is why a lot of people think it's crap that should probably be removed from PHP entirely.

    
    $stmt = $db->prepare('SELECT * FROM pageTable WHERE pageName = ? LIMIT 1');
    $stmt->bind_param('i', $_GET['page']);
    $stmt->execute();
    // then you have the headaches of bind_result here
    
    Code (markup):
    Mysqli's problems include people still using it the way they did mysql_, defeating the entire point... using the procedural wrappers that just add overhead because "wah wah, eye dunz wunna ware teh big boy panties", that ->query and ->exec do not use the same object type as prepare/execute, the bind mechanism that doesn't always fit the complexity - - or lack of complexity -- of the task at hand. It's really more of a hack than a solution which is part of why PDO was released so soon after.
     
    Last edited: Jul 1, 2020
    deathshadow, Jul 1, 2020 IP
    JEET likes this.
  17. JEET

    JEET Notable Member

    Messages:
    3,304
    Likes Received:
    351
    Best Answers:
    15
    Trophy Points:
    235
    #17
    @deathshadow
    Many thanks for this clarification
    Deeply appreciated
     
    JEET, Jul 1, 2020 IP