Question

Consider a.php:

<?php
 echo $_GET['a'];
?>

a.php?a=abcd' prints abcd\'.

I think PHP auto-escapes quotes, but I couldn't find a document about this.

Is it true? Because I want to make sure - I'm quite lazy so I didn't prevent SQLI in my PHP source codes..

Was it helpful?

Solution

Depends whether magic_quotes_gpc in On or not on your php.ini configuration file.

This configuration directive was introduced to help developers secure themselves against SQL Injection attacks, if you don't know what they are I suggest you read the Wikipedia entry very carefully.

The thing is, relying only on magic_quotes is insecure and unpredictable, and this feature will also be removed in future PHP versions, the best way to secure against SQL Injection is to either use prepared statements (with PDO or MySQLi) or use the specific escaping function for your database:

However, if magic_quotes is on and you try to escape your input data chances are you will get a double escaped string (which is not good), to counter-act this we usually detect if magic_quotes is On and, if it is, remove the added slashes via stripslashes().

Some do this before calling the database escaping function / method, but personally I prefer to do it upon page load since this will make the data much more consistent and less prone to errors, if you're using PHP 5.3+ the following snippet should disable magic_quotes:

if (get_magic_quotes_gpc() === 1)
{
    $_GET = json_decode(stripslashes(preg_replace('~\\\(?:0|a|b|f|n|r|t|v)~', '\\\$0', json_encode($_GET, JSON_HEX_APOS | JSON_HEX_QUOT))), true);
    $_POST = json_decode(stripslashes(preg_replace('~\\\(?:0|a|b|f|n|r|t|v)~', '\\\$0', json_encode($_POST, JSON_HEX_APOS | JSON_HEX_QUOT))), true);
    $_COOKIE = json_decode(stripslashes(preg_replace('~\\\(?:0|a|b|f|n|r|t|v)~', '\\\$0', json_encode($_COOKIE, JSON_HEX_APOS | JSON_HEX_QUOT))), true);
    $_REQUEST = json_decode(stripslashes(preg_replace('~\\\(?:0|a|b|f|n|r|t|v)~', '\\\$0', json_encode($_REQUEST, JSON_HEX_APOS | JSON_HEX_QUOT))), true);
}

If you are running an older version of PHP, the PHP Manual has a fairly good snippet too:

if (get_magic_quotes_gpc()) {
    $process = array(&$_GET, &$_POST, &$_COOKIE, &$_REQUEST);
    while (list($key, $val) = each($process)) {
        foreach ($val as $k => $v) {
            unset($process[$key][$k]);
            if (is_array($v)) {
                $process[$key][stripslashes($k)] = $v;
                $process[] = &$process[$key][stripslashes($k)];
            } else {
                $process[$key][stripslashes($k)] = stripslashes($v);
            }
        }
    }
    unset($process);
}

OTHER TIPS

PHP does this if magic_quotes_gpc is active in the configuration. This functionality is deprecated and will disappear in the future. It's not good (actually, it's outright stupid) to rely on deprecated functionality when writing new code.

Note that magic quotes is not enough to protect against SQL injections since it doesn't handle all character sets correctly. I recommend that you invert the magic quoting and use mysql_real_escape_string (or similar in other database extensions) instead.

You need to update your code to do proper escaping of your SQL input. Or even better, use PDO so you can pass query arguments separately from the query.

While PHP has magic_quotes_gpc it's disabled by default and will be removed in PHP6. Besides that it's a horrible mess leading to potentially insecure or faulty code and thus it's better to remove automatically added quotes if get_magic_quotes_gpc() is true.

mysqli_real_escape_string() is a good start

Maybe, maybe not. Magic Quotes is a config option. It should be turned off.

I'm quite lazy so I didn't prevent SQLI in my PHP source codes..

Magic quotes isn't enough to properly protect against SQL injection. Stop being lazy, start using bound parameters.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top