mysqli 准备好的语句和 mysqli_real_escape_string
Posted
技术标签:
【中文标题】mysqli 准备好的语句和 mysqli_real_escape_string【英文标题】:mysqli prepared statements and mysqli_real_escape_string 【发布时间】:2011-03-07 06:57:54 【问题描述】:传统上我使用 mysqli_real_escape_string 来转义用户输入。但是我正在考虑更改代码(希望尽可能少的步骤)以使用准备好的语句。
我想明确这一点 - 如果我使用准备好的语句来绑定我的所有变量,我可以确信 sql 注入是不可能的吗? (并且完全不用mysqli_real_escape_string?)
谢谢
【问题讨论】:
【参考方案1】:如果您正确绑定所有变量,您可以显着降低 SQL 注入的风险。如果您动态创建 SQL,仍然有可能获得 SQL 注入,例如:
'SELECT * FROM ' . $tablename . ' WHERE id = ?'
但如果你避免这样的事情,你不太可能会遇到问题。
【讨论】:
是的,请参阅sjmp.de/php/… 了解更多信息【参考方案2】:谈到安全性,如果您正确绑定或格式化变量,这两种方法之间没有区别。
绑定更简单,因为它可以用于任何情况,而转义不能(因此,您必须转换一些变量而不是转义/引用)。
另外,请记住,任何绑定或转义都不能使标识符安全。因此,如果您必须在查询中使用字段名称或运算符,则必须使用在脚本中硬编码的值。
【讨论】:
【参考方案3】:这是我对该主题的高级看法。
当使用动态 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
错误一样,我想总是有可能一个尚未发现(或新创建)的错误会使看似不可能的错误成为可能。
【讨论】:
以上是关于mysqli 准备好的语句和 mysqli_real_escape_string的主要内容,如果未能解决你的问题,请参考以下文章
从 mysql_query 转换为准备好的语句 (mysqli/PDO)?必要的?