【问题标题】:Is mysql_real_escape_string() broken?mysql_real_escape_string() 坏了吗?
【发布时间】:2011-07-14 10:07:48
【问题描述】:

有些人认为mysql_real_escape_string() 存在一些缺陷,即使正确使用也无法保护您的查询。
带上一些fossilized articles 作为证明。

所以,问题是:mysql[i]_real escape_string() 完全不能接受吗?
或者仍然可以使用这个函数来创建你自己的预处理语句?

请提供验证码。

【问题讨论】:

    标签: php mysql escaping sql-injection prepared-statement


    【解决方案1】:

    来自MySQL’s C API function mysql_real_escape_string description

    如果您需要更改连接的字符集,您应该使用mysql_set_character_set() 函数而不是执行SET NAMES(或SET CHARACTER SET)语句。 mysql_set_character_set() 的作用类似于SET NAMES,但也会影响mysql_real_escape_string() 使用的字符集,而SET NAMES 则不会。

    所以不要使用SET NAMES/SET CHARACTER SET,而是使用PHP’s mysql_set_charset 来更改编码,因为它与MySQL 的mysql_set_character_set 对应(参见source code of /ext/mysql/php_mysql.c)。

    【讨论】:

    • 好的,那么如果我们使用没有本地字符集设置方法的 mysqli 或 PDO 会发生什么?准备好的语句安全吗?
    • @Charles:MySQLi 确实有对应的函数:mysqli_set_charset。而对于prepared statements,使用preparing a string type时考虑的character_set_client system variable:“MYSQL_TYPE_STRING表示字符输入字符串数据。假定该值位于由character_set_client 系统变量指示的字符集中。”
    • 谢谢!那么,PDO 似乎是唯一缺少的。它有a charset param in the DSN,但它被标记为“当前被忽略..”
    • @Charles,在连接字符串中设置字符集是否有效? real_escape_string 这样可以正常工作吗?
    • @Pacerier,截至我四年前写该评论时,不,它曾经不起作用。 "DSN" == "连接字符串。"从那时起,如链接的手册页中所述,它已开始工作。
    【解决方案2】:

    但是,即使使用遗留代码和旧服务器版本,只有将数据库连接的字符集从像 Latin-1 的单字节字符集更改为允许值 0x5c ( ASCII 单引号)在多字节字符的第二个或更高字节中。

    具体来说,UTF-8 不允许这样做,这与 GBK 和 SJIS 等较旧的亚洲编码不同。因此,如果您的应用程序不更改连接字符集,或者仅将其更改为 UTF-8 或像 Latin-n 这样的单字节字符集,那么您就可以免受此攻击。

    但最佳做法仍然是运行最新的服务器版本,使用正确的界面来更改字符集,并使用准备好的查询,这样您就不会忘记转义内容。

    【讨论】:

      【解决方案3】:

      在 cmets 中有一个指向 mySQL 5.0.22 (24 May 2006) 中的错误修复的链接,该问题已在此处得到解决。

      【讨论】:

        猜你喜欢
        • 2010-11-21
        • 2021-12-31
        • 2015-03-04
        • 2016-09-08
        • 2020-09-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多