我目前使用mysqli php扩展。mysqli编写语句和mysqli_real_escape_string
传统上我使用mysqli_real_escape_string来转义用户输入。不过,我正在考虑更改代码(希望尽可能少的步骤)以使用预准备语句。
我想澄清一下 - 只要我使用准备好的语句来绑定我所有的变量,我可以确信sql注入是不可能的吗? (以及mysqli_real_escape_string完全放弃?)
感谢
我目前使用mysqli php扩展。mysqli编写语句和mysqli_real_escape_string
传统上我使用mysqli_real_escape_string来转义用户输入。不过,我正在考虑更改代码(希望尽可能少的步骤)以使用预准备语句。
我想澄清一下 - 只要我使用准备好的语句来绑定我所有的变量,我可以确信sql注入是不可能的吗? (以及mysqli_real_escape_string完全放弃?)
感谢
如果正确绑定所有的变量,你可以大大减少SQL注入的风险。它仍然是可能的,如果你动态地创建SQL例如获得一个SQL注入:
'SELECT * FROM ' . $tablename . ' WHERE id = ?'
但是,如果你避免这样的事情是不可能的,你将有问题。
说到安全性,如果您正确绑定或格式化变量,两种方法之间没有区别。
绑定只是简单的,因为它可以用于任何情况,而逃避不能(因此,你必须投下一些变量,而不是转义/引用)。
另外,请记住,没有绑定或转义可以使标识符安全。因此,如果您必须在查询中使用字段名称或运算符,则必须使用在您的脚本中硬编码的值。
这是我对该主题的高级视图。
使用动态SQL字符串时,您依赖的转义函数正常工作。不幸的是,这并非总是如此,因为在这个(公认岁)的例子可以看出:
http://dev.mysql.com/doc/refman/5.0/en/news-5-0-22.html
一旦你的数据值已经越狱,SQL字符串已经被解析和数据库编译服务器。如果转义函数没有正常完成其工作,或发现了新的SQL注入攻击,那么服务器可能会将数据误认为是SQL语句。
如果使用带有参数的预准备语句,则首先分析并编译语句。数据值在执行时与编译语句组合在一起。这将SQL逻辑从数据值中分离出来 - 有机会混淆两个应该不会出现。
所以,是的,你可以免除mysqli_real_escape_string
,但我不会说使用带参数的预准备语句使SQL注入变得不可能。这使得它变得更加困难,但是如同mysqli_real_escape_string
的错误,我想总有一个机会,一个尚未被发现(或新创建)的bug会使这个看起来不可能的,可能的。
是,请参阅http://www.sjmp.de/php/php-mysql-mehr-sicherheit-und-erhoehte-performance-durch-mysqli-und-prepared-statements/了解更多信息 – Tobias 2011-03-09 10:21:42