替代mysql_real_escape_string而不连接到DB

时间:2009-07-22 00:38:49

标签: 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

4 个答案:

答案 0 :(得分:70)

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

如果您只是测试,那么您也可以使用mysql_escape_string(),它不能100%保证不会出现SQL注入攻击,但如果没有数据库连接,就无法构建更安全的东西。

答案 1 :(得分:60)

好吧,根据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);
}

答案 2 :(得分:23)

与我的另一个答案直接相反,即使使用多字节字符,以下函数也可能是安全的。

// 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;
}

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

答案 3 :(得分: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';

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

SET GLOBAL sql_mode='NO_BACKSLASH_ESCAPES';

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

另见Bug#8303。