我希望有一个函数表现为mysql_real_escape_string而不连接数据库,因为有时我需要在没有数据库连接的情况下进行干测试。不推荐使用mysql_escape_string,因此不合需要。我的一些发现:
http://www.gamedev.net/community/forums/topic.asp?topic_id=448909
答案 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。