替代mysql_real_escape_string而不连接到DB

Vie*_*iet 86 php mysql mysql-real-escape-string

我希望有一个函数表现为mysql_real_escape_string而不连接数据库,因为有时我需要在没有数据库连接的情况下进行干测试.不推荐使用mysql_escape_string,因此不合需要.我的一些发现:

http://www.gamedev.net/community/forums/topic.asp?topic_id=448909

http://w3schools.invisionzone.com/index.php?showtopic=20064

too*_*php 72

没有数据库连接就无法安全地转义字符串.mysql_real_escape_string()准备好的语句需要连接到数据库,以便它们可以使用适当的字符集转义字符串 - 否则使用多字节字符仍然可以进行SQL注入攻击.

如果你只是测试,那么你也可以使用mysql_escape_string(),它不是100%保证免受SQL注入攻击,但没有数据库连接就不可能构建任何更安全的东西.

  • 是的,如果你知道字符集,什么阻止在没有连接的情况下进行转义? (7认同)
  • 我已经获得了一些旧的代码来更新.它使用`mysql_escape_string`而没有连接(仍试图找出原因).由于该函数已被弃用,我只是想知道如何替换它.在没有打开连接的情况下,无论何种函数替换它都可以指定"适当的字符集",这似乎是合理的. (2认同)
  • 不可能?mysql_real_escape_string从数据库连接获得的是什么,而不是可以手动传递给等效函数的配置数据?编辑:刚看下面,它在MySQL中调用了一个库函数,因此有一些处理发生在PHP之外.它可能仍然是可移植的,但保持它是最新的本身就是一个项目. (2认同)
  • 如果提前知道数据库字符集怎么办? (2认同)

zom*_*bat 62

好吧,根据mysql_real_escape_string函数引用页面:"mysql_real_escape_string()调用MySQL的库函数mysql_real_escape_string,它会转义以下字符:\ x00,\n,\ r,\,',"和\ x1a."

考虑到这一点,那么您发布的第二个链接中给出的功能应该完全符合您的需求:

function mres($value)
{
    $search = array("\\",  "\x00", "\n",  "\r",  "'",  '"', "\x1a");
    $replace = array("\\\\","\\0","\\n", "\\r", "\'", '\"', "\\Z");

    return str_replace($search, $replace, $value);
}
Run Code Online (Sandbox Code Playgroud)

  • -1这非常危险.如果数据库连接使用多字节字符集,那么像这样的简单字节替换可能会导致数据损坏(包括转义/引用字符) - 这可能被恶意攻击者故意利用来注入任意SQL. (15认同)
  • 谢谢.我建议别的东西:函数转义($ aQuery){return strtr($ aQuery,array("\ x00"=>'\ x00',"\n"=>'\n',"\ r"=> '\ r','\\'=>'\\\\',"'"=>"\'",'''=>'\"',"\ x1a"=>'\ x1a')) ; } (6认同)

too*_*php 25

与我的其他答案直接相反,即使使用多字节字符,以下函数也可能是安全的.

// replace any non-ascii character with its hex code.
function escape($value) {
    $return = '';
    for($i = 0; $i < strlen($value); ++$i) {
        $char = $value[$i];
        $ord = ord($char);
        if($char !== "'" && $char !== "\"" && $char !== '\\' && $ord >= 32 && $ord <= 126)
            $return .= $char;
        else
            $return .= '\\x' . dechex($ord);
    }
    return $return;
}
Run Code Online (Sandbox Code Playgroud)

我希望比我自己知识渊博的人能告诉我为什么上面的代码不起作用......

  • \ xAA实际上是指MySQL字符串文字中的文本"xAA"吗?文档似乎说\ x没有任何特殊含义,因此\将被忽略.http://dev.mysql.com/doc/refman/5.0/en/string-literals.html (2认同)

Vie*_*iet 6

通过进一步的研究,我发现:

http://dev.mysql.com/doc/refman/5.1/en/news-5-1-11.html

安全修复:

在多字节编码处理中发现了SQL注入安全漏洞.该错误发生在服务器中,错误地解析了使用mysql_real_escape_string()C API函数转义的字符串.

Josh Berkus和Tom Lane发现并报告了此漏洞,作为OSDB联盟项目间安全协作的一部分.有关SQL注入的更多信息,请参阅以下文本.

讨论.在多字节编码处理中发现了SQL注入安全漏洞.SQL注入安全漏洞可以包括这样一种情况,即当用户提供要插入数据库的数据时,用户可能会将SQL语句注入服务器将执行的数据中.关于此漏洞,当使用字符集 - 不知道转义(例如,PHP中的addslashes())时,可以绕过某些多字节字符集(例如,SJIS,BIG5和GBK)中的转义.因此,诸如addslashes()之类的函数无法阻止SQL注入攻击.在服务器端修复此问题是不可能的.最好的解决方案是让应用程序使用mysql_real_escape_string()等函数提供的字符集感知转义.

但是,在MySQL服务器如何解析mysql_real_escape_string()的输出时检测到一个错误.因此,即使使用了字符集感知函数mysql_real_escape_string(),也可以进行SQL注入.此错误已得到修复.

解决方法.如果您无法将MySQL升级到包含mysql_real_escape_string()解析中的错误修复程序的版本,但运行MySQL 5.0.1或更高版本,则可以使用NO_BACKSLASH_ESCAPES SQL模式作为解决方法.(此模式是在MySQL 5.0.1中引入的.)NO_BACKSLASH_ESCAPES启用SQL标准兼容模式,其中反斜杠不被视为特殊字符.结果将是查询将失败.

要为当前连接设置此模式,请输入以下SQL语句:

SET sql_mode='NO_BACKSLASH_ESCAPES';
Run Code Online (Sandbox Code Playgroud)

您还可以为所有客户端全局设置模式:

SET GLOBAL sql_mode='NO_BACKSLASH_ESCAPES';
Run Code Online (Sandbox Code Playgroud)

通过使用命令行选项--sql-mode = NO_BACKSLASH_ESCAPES或在服务器选项文件中设置sql-mode = NO_BACKSLASH_ESCAPES(例如,my.cnf或my.ini),可以在服务器启动时自动启用此SQL模式,取决于您的系统).(Bug#8378,CVE-2006-2753)

另见Bug#8303.

  • 还要注意`NO_BACKSLASH_ESCAPES` [引入其他漏洞](http://stackoverflow.com/a/23277864/623041). (2认同)
  • 已在5.1.11中修复 - 链接已断开,此处为存档:https://web.archive.org/web/20120501203047/http://dev.mysql.com:80/doc/refman/5.1/en/新闻5-1-11.html (2认同)