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

时间:2009-08-02 23:37:46

标签: php mysql sql-injection

http://www.justinshattuck.com/2007/01/18/mysql-injection-cheat-sheet/?akst_action=share-this上,有一个部分声称可以绕过具有某些亚洲字符编码的mysql_real_escape_string

  

使用BIG5或GBK绕过mysql_real_escape_string()

     

“注入字符串”
  に关する追加情报:

     上面的字符是中文Big5

这是真的吗?如果是这样,如果您无法访问预先准备好的声明,您将如何保护您的网站不受此影响?

4 个答案:

答案 0 :(得分:25)

根据Stefan Esser的说法,使用mysql_real_escape_string()SET NAMES [是]不安全。”

他的解释,from his blog

  

SET NAMES通常用于将编码从默认编码切换到应用程序所需的编码。   这是以mysql_real_escape_string不知道的方式完成的。这意味着如果你切换到一些允许反斜杠作为第二个第3个第4个...字节的多字节编码,你会遇到麻烦,因为mysql_real_escape_string没有正确转义。 UTF-8是安全的......

     

更改编码的安全方法是mysql_set_charset,但这仅适用于新的PHP版本

他确实提到UTF-8是安全的。

答案 1 :(得分:19)

这是一个MySQL服务器错误,据报道已于2006年5月修复。

请参阅:

在MySQL 4.1.20,5.0.22,5.1.11中修复了该错误。

如果使用4.1.x,5.0.x或5.1.x,请确保至少已升级到次要修订号。

作为一种变通方法,您还可以启用SQL模式NO_BACKSLASH_ESCAPES,该模式禁用反斜杠作为引用转义字符。

答案 2 :(得分:3)

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

答案 3 :(得分:1)

正如其他人所证明的那样,mysql_real_escape_string() can be bypassed in obscure edge cases。这是绕过逃逸逻辑的一种已知策略,但可能还有其他尚未发现的未知漏洞。

prevent SQL injection in PHP的简单有效方法是尽可能使用预备语句,并使用非常严格的白名单。

准备好的语句,当实际使用而不是由PDO驱动程序模拟时,可证明是安全的(至少在SQL注入方面),因为它们解决了应用程序安全性的基本问题:它们分离了数据来自对数据进行操作的说明。他们分开发送;参数化的值永远不会有污染查询字符串。

2015年。不要再逃避和连接了。您仍应根据应用程序(和业务)逻辑验证输入,但只使用预准备语句。