2010-06-23 91 views
6

我目前使用mysqli php扩展。mysqli编写语句和mysqli_real_escape_string

传统上我使用mysqli_real_escape_string来转义用户输入。不过,我正在考虑更改代码(希望尽可能少的步骤)以使用预准备语句。

我想澄清一下 - 只要我使用准备好的语句来绑定我所有的变量,我可以确信sql注入是不可能的吗? (以及mysqli_real_escape_string完全放弃?)

感谢

回答

5

如果正确绑定所有的变量,你可以大大减少SQL注入的风险。它仍然是可能的,如果你动态地创建SQL例如获得一个SQL注入:

'SELECT * FROM ' . $tablename . ' WHERE id = ?' 

但是,如果你避免这样的事情是不可能的,你将有问题。

+0

是,请参阅http://www.sjmp.de/php/php-mysql-mehr-sicherheit-und-erhoehte-performance-durch-mysqli-und-prepared-statements/了解更多信息 – Tobias 2011-03-09 10:21:42

4

说到安全性,如果您正确绑定或格式化变量,两种方法之间没有区别。

绑定只是简单的,因为它可以用于任何情况,而逃避不能(因此,你必须投下一些变量,而不是转义/引用)。

另外,请记住,没有绑定或转义可以使标识符安全。因此,如果您必须在查询中使用字段名称或运算符,则必须使用在您的脚本中硬编码的值。

2

这是我对该主题的高级视图。

使用动态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会使这个看起来不可能的,可能的。