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 php 扩展。

传统上我使用 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的主要内容,如果未能解决你的问题,请参考以下文章

使用 mysqli 和准备好的语句时命令不同步 [重复]

MySQLi:使用一个准备好的语句插入多行

如何使用mysqli准备好的语句?

从 mysql_query 转换为准备好的语句 (mysqli/PDO)?必要的?

如何在mysqli准备好的语句中使用SQL LIKE子句[重复]

什么时候在 PHP Mysqli 中使用准备好的语句? - 用户表单搜索输入与选择查询