php - mysql_escape_string 漏洞

标签 php mysql prepared-statement

最近我在向我的 friend 解释参数化及其优势,他问我在安全性方面它比 mysqli_escape_string 有什么好处。具体来说,您能想到尽管输入字符串被转义(使用 mysqli_escape_string)仍会成功的任何 SQL 注入(inject)示例吗?

更新:

对于我最初的问题不够清楚,我深表歉意。这里提出的一般问题是,尽管转义了输入字符串,是否可能进行 SQL 注入(inject)?

最佳答案

更新的答案

问题经过编辑(在我的回答发布后)专门针对 mysqli_escape_string,它是 mysql_real_escape_string 的别名,因此考虑了连接编码。这使得原始答案不再适用,但为了完整起见,我将其保留。

简而言之,新答案:mysqli_escape_string 在安全方面与参数化查询一样好,前提是您不要搬起石头砸自己的脚

具体来说,PHP doc page 上的巨大警告中突出显示了您不能做的事情。 :

The character set must be set either at the server level, or with the API function mysqli_set_charset() for it to affect mysqli_real_escape_string().

如果您不注意此警告(即,如果您使用直接的 SET NAMES 查询更改字符集)并且您将字符集从单个 -字节编码转换为“方便的”(从攻击者的角度来看)多字节编码,您实际上模拟了愚蠢的 mysql_escape_string 所做的事情:在不知道输入采用哪种编码的情况下尝试转义字符。

如以下原始答案所述,这种情况使您可能容易受到 SQL 注入(inject)攻击。

重要说明:我记得在某处读到最近的 MySql 版本已经在其末端(在客户端库中)堵上了这个漏洞,这意味着您可能是完美的即使使用 SET NAMES 切换到易受攻击的多字节编码也是安全的。但请不要相信我的话。

原始答案

mysql_real_escape_string 相比,裸 mysql_escape_string 不考虑 connection encoding .这意味着它假定输入采用单字节编码,而实际上它可以合法地采用多字节编码。

一些多字节编码具有对应于单个字符的字节序列,其中一个字节是单引号的 ASCII 值 (0x27);如果输入这样的字符串,mysql_escape_string 将愉快地“转义引号”,这意味着将 0x27 替换为 0x5c 0x27 .根据编码规则,这可能导致将多字节字符突变为包含 0x5c 的另一个字符,并将“剩余的”0x27 作为独立的单个字符在输入中引用。瞧,您已将未转义的引号注入(inject)到 SQL 中。

有关详细信息,请参阅 this blog post .

关于php - mysql_escape_string 漏洞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13026469/

相关文章:

php - 在 Laravel 中 Dio 为空的 Flutter 文件上传

php - 表中带有子类别的类别 - PHP + MYSQL

mysql - : before a value in sql mean? 是什么意思

java - PreparedStatement 返回 "You have an error in your SQL syntax"

php - 执行查询加载页面

php - 在 PHP 上安装 Lapack

php - 使用 shell 和 ImageMagick 递归调整图像大小

mysql - Nodejs函数返回未定义,尽管回调参数有值

MySQL : how to group multiple row into one row

php - 准备好的语句在 mySQL/PHP 中不起作用