简体   繁体   English

mysql_real_escape_string()是否完全防止SQL注入?

[英]Does mysql_real_escape_string() FULLY protect against SQL injection?

On http://www.justinshattuck.com/2007/01/18/mysql-injection-cheat-sheet/?akst_action=share-this , there is a section that claims you can bypass mysql_real_escape_string with certain Asian character encodings http://www.justinshattuck.com/2007/01/18/mysql-injection-cheat-sheet/?akst_action=share-this上 ,有一节声称可以绕过某些亚洲字符编码的mysql_real_escape_string

Bypassing mysql_real_escape_string() with BIG5 or GBK 用BIG5或GBK绕过mysql_real_escape_string()

"injection string" “注射线”
に関する追加情報: に关する追加情报:

the above chars are Chinese Big5 上面的字符是中文Big5

Is this really true? 这是真的吗? And if so, how would you protect your website against this, if you had no access to prepared statements? 如果是这样,如果您无法访问预先准备好的声明,您将如何保护您的网站不受此影响?

According to Stefan Esser, " mysql_real_escape_string() [is] not safe when SET NAMES is used." 根据Stefan Esser的说法, “当使用SET NAMESmysql_real_escape_string()不安全。”

His explanation, from his blog : 他的解释来自他的博客

SET NAMES is usually used to switch the encoding from what is default to what the application needs. SET NAMES通常用于将编码从默认编码切换到应用程序所需的编码。 This is done in a way that mysql_real_escape_string doesn't know about this. 这是以mysql_real_escape_string不知道的方式完成的。 This means if you switch to some multi byte encoding that allows backslash as 2nd 3rd 4th… byte you run into trouble, because mysql_real_escape_string doesn't escape correctly. 这意味着如果你切换到一些允许反斜杠作为第二个第3个第4个...字节的多字节编码,你会遇到麻烦,因为mysql_real_escape_string没有正确转义。 UTF-8 is safe… UTF-8很安全......

Safe way to change encoding is mysql_set_charset , but that is only available in new PHP versions 更改编码的安全方法是mysql_set_charset ,但这仅适用于新的PHP版本

He does mention that UTF-8 is safe, though. 但他确实提到UTF-8是安全的。

This is a MySQL server bug that was reportedly fixed way back in May 2006. 这是一个MySQL服务器错误,据报道已于2006年5月修复。

See: 看到:

The bug was reported fixed in MySQL 4.1.20, 5.0.22, 5.1.11. 在MySQL 4.1.20,5.0.22,5.1.11中修复了该错误。

If you use 4.1.x, 5.0.x, or 5.1.x, make sure you have upgraded at least to the minor revision numbers. 如果使用4.1.x,5.0.x或5.1.x,请确保至少已升级到次要修订号。

As a workaround, you can also enable the SQL mode NO_BACKSLASH_ESCAPES which disables backslash as a quote-escape character. 作为解决方法,您还可以启用SQL模式NO_BACKSLASH_ESCAPES ,该模式禁用反斜杠作为引用转义字符。

我很确定如果使用SQL来更改char编码,它只会起作用。

As others have demonstrated, mysql_real_escape_string() can be bypassed in obscure edge cases . 正如其他人所证明的那样, mysql_real_escape_string()可以在不起眼的边缘情况下被绕过 That's one known strategy for bypassing the escaping logic, but there could be other unknown vulnerabilities that have not been discovered yet. 这是绕过逃逸逻辑的一种已知策略,但可能还有其他尚未发现的未知漏洞。

The simple and effective way to prevent SQL injection in PHP is to use prepared statements where you can, and a very strict whitelist where you can't. 在PHP中防止SQL注入的简单而有效的方法是尽可能使用预准备语句 ,并且在不可能的情况下使用非常严格的白名单。

Prepared statements, when actually used and not emulated by the PDO driver, are provably secure (at least with regards to SQL injection), as they solve a fundamental problem with application security: they separate the data from the instructions that operate on the data. 准备好的语句,当实际使用而不是由PDO驱动程序模拟时,可证明是安全的(至少在SQL注入方面),因为它们解决了应用程序安全性的基本问题:它们将数据与操作数据指令分开。 They're sent in separate packets; 它们是分开发送的; the parameterized values never have a chance to taint the query string. 参数化值永远不会有污染查询字符串的机会。

It's 2015. Don't escape and concatenate anymore. 这是2015年。不要再逃避和连接了。 You should still validate your inputs according to application (and business) logic, but just use prepared statements. 您仍应根据应用程序(和业务)逻辑验证输入,但只使用预准备语句。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM