我希望有一个函数表现为 mysql_real_escape_string 而不连接到数据库,因为有时我需要在没有数据库连接的情况下进行干测试。mysql_escape_string 已被弃用,因此是不可取的。我的一些发现:
http://www.gamedev.net/community/forums/topic.asp?topic_id=448909
我希望有一个函数表现为 mysql_real_escape_string 而不连接到数据库,因为有时我需要在没有数据库连接的情况下进行干测试。mysql_escape_string 已被弃用,因此是不可取的。我的一些发现:
http://www.gamedev.net/community/forums/topic.asp?topic_id=448909
没有数据库连接就不可能安全地转义字符串。mysql_real_escape_string()
准备好的语句需要与数据库的连接,以便它们可以使用适当的字符集转义字符串 - 否则仍然可能使用多字节字符进行 SQL 注入攻击。
如果您只是在测试,那么您不妨使用mysql_escape_string()
它,它不能 100% 保证免受 SQL 注入攻击,但如果没有数据库连接,就不可能构建任何更安全的东西。
好吧,根据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);
}
与我的其他答案直接相反,即使使用多字节字符,以下功能也可能是安全的。
// 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;
}
我希望比我更有知识的人能告诉我为什么上面的代码不起作用......
通过进一步的研究,我发现:
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中的addlashes()),可以绕过一些多字节字符集(例如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 模式也可以在服务器启动时自动启用,方法是使用命令行选项 --sql-mode=NO_BACKSLASH_ESCAPES 或在服务器选项文件中设置 sql-mode=NO_BACKSLASH_ESCAPES(例如,my.cnf 或 my.ini ,取决于您的系统)。(错误#8378,CVE-2006-2753)
另见错误#8303。