mysql_real_escape_string的替代方法,无需连接到数据库
我想有一个函数的行为像mysql_real_escape_string没有连接到数据库,因为有时我需要做干testing没有数据库连接。 mysql_escape_string已被弃用,因此是不可取的。 我的一些发现:
http://www.gamedev.net/community/forums/topic.asp?topic_id=448909
http://w3schools.invisionzone.com/index.php?showtopic=20064
没有数据库连接就无法安全地转义string。 mysql_real_escape_string()
和准备好的语句需要连接到数据库,以便它们可以使用适当的字符集转义string – 否则SQL注入攻击仍然可以使用多字节字符。
如果你只是在testing ,那么你可以使用mysql_escape_string()
,它不是100%保证免受SQL注入攻击,但是没有数据库连接就不可能build立更安全的东西。
那么根据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注入安全漏洞。 该错误在服务器中,错误地parsing了使用mysql_real_escape_string()C API函数转义的string。
这个漏洞被Josh Berkus和Tom Lane发现并报告,作为OSDB联盟的项目间安全合作的一部分。 有关SQL注入的更多信息,请参阅以下文本。
讨论。 在多字节编码处理中发现SQL注入安全漏洞。 SQL注入安全漏洞可能包含一种情况,即当用户提供要插入数据库的数据时,用户可能会将SQL语句注入到服务器将执行的数据中。 关于此漏洞,使用字符集不知道的转义(例如PHP中的addslashes())时,可能会绕过某些多字节字符集(例如SJIS,BIG5和GBK)中的转义。 因此,诸如addslashes()之类的函数不能防止SQL注入攻击。 这是不可能解决这个在服务器端。 最好的解决scheme是应用程序使用函数mysql_real_escape_string()提供字符集感知的转义。
但是,MySQL服务器如何分析mysql_real_escape_string()的输出,却发现了一个错误。 因此,即使使用了字符集感知函数mysql_real_escape_string(),SQL注入也是可能的。 这个bug已经修复。
解决方法。 如果您无法将MySQL升级到包含mysql_real_escape_string()parsing中的缺陷修复的版本,但运行MySQL 5.0.1或更高版本,则可以使用NO_BACKSLASH_ESCAPES SQL模式作为解决方法。 (这种模式是在MySQL 5.0.1中引入的。)NO_BACKSLASH_ESCAPES启用了SQL标准兼容模式,其中反斜杠不被视为特殊字符。 结果将是查询将失败。
要为当前连接设置此模式,请input以下SQL语句:
SET sql_mode='NO_BACKSLASH_ESCAPES';
您也可以为所有客户端全局设置模式:
SET GLOBAL sql_mode='NO_BACKSLASH_ESCAPES';
当服务器启动时,也可以通过使用命令行选项–sql-mode = NO_BACKSLASH_ESCAPES或在服务器选项文件中设置sql-mode = NO_BACKSLASH_ESCAPES(例如my.cnf或my.ini ,这取决于你的系统)。 (错误#8378,CVE-2006-2753)
参见Bug#8303。