我们都知道,我们应该使用准备好的语句或适当的替换/格式规则,以防止SQL注入在我们的应用。
然而,在字符文字的MySQL的列表考虑看看的时候,我注意到,它包括以下特点:
-
\0
一个ASCII NUL( 0x00
)字符。 -
\'
单引号( '
)字符。 -
\"
双引号( "
)字符。 -
\b
甲退格字符。 -
\n
的换行(换行)字符。 -
\r
一个回车符。 -
\t
制表符。 -
\Z
ASCII 26( 按Ctrl + Z)。 见注桌子下面。 -
\\
反斜杠( \
)字符。 -
\%
甲%
字符。 -
\_
一个_
字符。
现在,虽然%
和_
字符需要,以防止不必要的通配符插入到LIKE语句注射逃跑了,而'
(单引号), \
(反斜线)和"
(双引号)都需要进行转义为了防止任意的SQL注入 - ?可能具有这些其他字符转义的的直接导致SQL注入漏洞,否则不会现在没有人有这样的任何真实世界的例子一个漏洞?
假设我们正在建立我们的查询,如:
SELECT * FROM users WHERE username='$user'
是否有任何值$user
,其中只有不转义字符文字被\b
(退格键), \0
(NUL), \n
(换行), \r
(换行), \t
(制表符)或\Z
(Ctrl + Z 键 ),允许注入任意SQL进入此查询?
考虑到从下面线mysql_real_escape_string()手册:
MySQL的只要求反斜杠和用于引用查询字符串转义引号字符。 mysql_real_escape_string()引用了其他字符,以使它们更容易在日志文件中读取。
在MySQL SQL注入不应该有可能与这些特殊字符单独自己: \b
\0
\n
\r
\t
\Z
。
然而字符串文字手册指出以下但原因指定的(或不)不涉及SQL注入:
如果你想插入二进制数据到字符串列(如BLOB列),你应该代表了转义序列某些字符。 反斜杠(“\”),并用于引用该字符串的引号字符必须进行转义。 在某些客户端环境,它也可能是必要的逸出NUL或控制+ Z。 在MySQL的客户端截断包含NULL字符,如果他们没能逃过引用的字符串,并控制+ Z,可以采取档案结尾在Windows上,如果没有逃脱。
此外,在一个简单的测试,而不管天气的上面列出的特殊字符被转义与否,MySQL的产生相同的结果。 换句话说MySQL并没有连记:
$query_sql = "SELECT * FROM `user` WHERE user = '$user'";
上面的查询同样就职于非逃脱,逃脱上面列出的那些字符的版本为下面放:
$user = chr(8); // Back Space
$user = chr(0); // Null char
$user = chr(13); // Carriage Return
$user = chr(9); // Horizontal Tab
$user = chr(26); // Substitute
$user = chr(92) .chr(8); // Escaped Back Space
$user = chr(92) .chr(0); // Escaped Null char
$user = chr(92) .chr(13); // Escaped Carriage Return
$user = chr(92) .chr(9); // Escaped Horizontal Tab
$user = chr(92) .chr(26); // Escaped Substitute
测试表,并在简单的测试使用的数据:
-- Table Structure
CREATE TABLE IF NOT EXISTS `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user` varchar(10) CHARACTER SET utf8 NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- Table Data
INSERT INTO `user` ( `user` ) VALUES
( char( '8' ) ),
( char( '0' ) ),
( char( '10' ) ),
( char( '13' ) ),
( char( '9' ) ),
( char( '26' ) );
有没有这样的字符。
有你的问题两种错误的做法语句,导致您混淆:
- 我们都知道,我们应该以防止SQL注入使用我们的应用......适当的替换规则。
这是错误的说法。 不更换,但格式 。 这是本质的东西。 替换,并不防止打针,而格式化一样。 请注意查询的每个不同的部分需要哪些是无用的任何其他部分不同的格式。 再说了,还有另外一个特点,对注射保护至关重要 - 反引号(')。 但是你,因为它没有任何与字符串文字没有列出。
- 的'(单引号),\(反斜线)和“(双引号)都需要以防止注射进行转义
这是非常错误的语句。 逃离不会阻止打针! 这些字符必须以转义格式化字符串并有绝对无关,与注射。 虽然这是事实,正确格式化查询部分是针对注射无懈可击。 但事实是 - 你必须格式化动态查询部分只是它的缘故,要遵循语法规则 - 因为不管注射的不是。 你将有你的查询坚不可摧只是作为一个结果。
现在你可以看到为什么你的最后一句话,
为什么所有这些其他的字符足以容易通过mysql_real_escape_string转义,因为它不是立即明显给我。
是错的说:
这是字符串格式化规则要求这些字符,没有任何“漏洞”。 他们中的一些逃脱只是为了方便,有些是为了便于阅读,一些转义分隔符的明显的原因。 就这样。
要回答评论最新的问题:
我真的要一个答案,因为PHP的mysql_real_escape_string没有任何引用这些文字。
还是那句话:虽然平均PHP用户的心mysql_real_escape_string()
强烈连接到任何疤痕注射, 在现实中却并非如此。 有没有“危险”的角色之一。 没有一个人。 有特殊含义的一些服务字符。 他们在某些情况下进行转义,取决于上下文。
因此,和任何“危险”这个功能转义字符之间没有连接。 你开始思考,当下mysql_real_escape_string()
的目的是逃避‘危险’人物,你确实变得危险。 虽然只要您使用此功能只逃脱字符串(无条件这样做) -你可以考虑自己的安全(当然,如果你不忘记格式化所有其他文字也使用各自格式规则)
我想知道,如果“%”字符会导致什么比额外的结果更加like子句中。
没有。