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