要防止SQL注入,是否需要在mysql_real_escape_string()
启用时使用magic_quotes_gpc
?
答案 0 :(得分:5)
对于一些罕见的编码,such as GBk - 是的
但你不应该因为这个原因而回复它。无论如何都应该关闭魔术引号(并且将在下一个PHP版本中)。所以,mysql_real_escape_string()是唯一的转义函数。注意它不是sql注入预防功能。许多人不明白这一点:它只是语法的一部分。它必须用于不“保护”任何东西,而是用于组装语法正确的SQL查询。无论数据来自哪里,每次构建查询时都必须使用它。当然它也可以保护你免受SQL注入,作为副作用
当然,mysql_real_escape_string()
仅适用于带引号的字符串。所以,如果你这样做
$num=mysql_real_escape_string($num);
$sql="SELECT INTO table SET data=$num"; /BAD!!!
它不会保护任何东西。 如果您要使用未加引号的数字,则必须将其强制转换为强制类型,如下所示:
$num=intval($num);
$sql="SELECT INTO table SET data=$num"; /GOOD
mysql_real_escape_string()
按预期工作,应设置正确的客户端编码,并且可能仅具有mysql_set_charset()
函数,SET NAMES查询不会设置那个。如果你想摆脱所有这些复杂性,你可以使用prepared statements,虽然你需要将你的mysql驱动程序切换到mysqli或PDO。
请注意,没有正确的语法或准备好的语句不会帮助您使用除文字之外的查询部分。你无法逃脱标识符或运算符。如果您碰巧动态使用这些部分,则必须在脚本中对其进行硬编码,如下所示(对于ORDER BY子句):
$orders=array("name","price","qty");
$key=array_search($_GET['sort'],$orders));
$orderby=$orders[$key];
$query="SELECT * FROM `table` ORDER BY $orderby";
或者这个(WHERE子句)
$w=array();
if (!empty($_GET['rooms'])) $w[]="rooms='".mysql_real_escape_string($_GET['rooms'])."'";
if (!empty($_GET['space'])) $w[]="space='".mysql_real_escape_string($_GET['space'])."'";
if (!empty($_GET['max_price'])) $w[]="price < '".mysql_real_escape_string($_GET['max_price'])."'";
if (count($w)) $where="WHERE ".implode(' AND ',$w); else $where='';
$query="select * from table $where";
答案 1 :(得分:1)
查看文档; http://php.net/manual/en/function.mysql-real-escape-string.php
注意:如果启用了magic_quotes_gpc,请先将stripslashes()应用于数据。对已经转义的数据使用此函数将两次转义数据。
你可以检查magic_quotes_gpc是否打开,参见示例; http://php.net/manual/en/function.get-magic-quotes-gpc.php
答案 2 :(得分:0)
是的,通过过滤器mysql_real_escape_string()来运行进入sql语句的所有值的好习惯不仅仅是过滤器正在修复的引用。
它可以防止注入攻击,请参阅该方法的php手册中的示例。
http://php.net/manual/en/function.mysql-real-escape-string.php
答案 3 :(得分:0)
不,是的。如果启用了magic_quotes
并且应用了mysql_real_escape_string
,那么一些转义将加倍,这会导致我在某些论坛上看到的“It\'s an example.
”之类的内容。对于最佳实践,您应该禁用magic_quotes
并始终使用mysql_real_escape_string
,甚至更好地使用数据库抽象库。