开发者

Does PHP auto escape quotes in a string which is passed by GET or POST?

Consider file a.php:

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

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

I think PHP auto escape 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 SQL injection开发者_JAVA百科 in my PHP source code...


It depends on 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:

  • PDO::quote()
  • mysql_escape_string() or better yet mysql_real_escape_string()

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 counteract 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);
}


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 PHP 6. 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜