我们都知道,我们应该使用准备好的语句或适当的替换/格式化规则,以防止sql注入到我们的应用程序中。
然而,在查看MySQL的字符文本列表时,我注意到它包括以下字符:
0x00)字符
- 一个单引号(
')字符
双引号(
“
)字符\r
回车符现在,虽然需要对%
和
'
(单引号),
\
(双引号)都需要转义,以防止任意SQL的注入-如果未转义这些字符中的任何一个,是否会直接导致SQL注入漏洞,否则就不会存在?是否有人有任何此类漏洞的真实示例?(反斜杠),和
“
假设我们正在构建查询,如下所示:
SELECT * FROM users WHERE username='$user'
如果唯一未转义的字符文本是允许向该查询中注入任意SQL的
\b(backspace)、
\0(NUL)、
\n(newline)、
\r(linefeed)、
\t(tab)或
\Z(Ctrl>\kbd>Z),那么是否有任何值用于
$user(用户)>?
2020年起的强制性增编:
你必须使用事先准备好的语句,忘记逃跑、“危险人物”或其他任何事情。
使用参数化查询被认为是防止SQL注入的唯一正确方法,原因如下:
哪些字符实际上能够导致mysql中的SQL注入
导致SQL注入的不是“字符”。但格式不正确。根据具体情况,任何角色都可能是“危险的”或绝对无害的。将保护限制在某个子集是一种危险的错觉,它迟早会导致SQL注入。
你的问题中有两个错误的陈述导致了你的困惑:
这种说法是错误的。不是替换,而是格式化。这一区别至关重要。仅替换不能防止注入,而格式化可以。请注意,查询的每个不同部分都需要不同的格式,这对于任何其他部分都是无用的。比方说,还有另一个字符,对于注射保护来说是必不可少的-一个反勾号(`)。但您没有列出它,因为它与字符串文字无关。
这是一个严重错误的说法。转义不会阻止注入。这些字符需要转义才能格式化字符串,与注入绝对无关。虽然正确格式化的查询部分确实是无懈可击的。但事实是——您必须格式化动态查询部分只是为了它,遵循语法规则,而不是因为任何注入。作为副作用,您将使您的查询无法穿透。
现在你可以明白为什么你的上一句话,
为什么所有这些其他字符都容易被mysql\u real\u escape\u string转义,因为我现在还不清楚。
错误地说:
字符串格式规则需要这些字符,而不是任何“漏洞”。其中一些转义只是为了方便,一些是为了易读性,一些是为了转义分隔符。仅此而已。
要回答评论中最近的问题:
我真的很想知道答案,因为PHP的mysql\u real\u escape\u字符串也没有引用这些文字。
再次强调:虽然在普通PHP用户看来,mysql\u real\u escape\u string()与任何令人恐惧的注入都有很强的关联,但实际上并非如此。没有“危险”字符。一个也没有。有一些具有特殊含义的服务字符。在某些情况下,他们必须逃脱,这取决于上下文。
因此,此函数转义的字符与任何“危险”之间没有联系。当您开始认为mysql_real_escape_string()
的目的是转义“危险”字符时,您确实将自己置于危险之中。只要您仅使用此函数转义字符串(并且无条件地这样做),您可能会认为自己是安全的(当然,如果您没有忘记使用各自的格式规则格式化所有其他文字)
我想知道在LIKE子句中,“%”字符是否会导致除额外结果以外的任何结果。
不
匿名用户
考虑mysql\u real\u escape\u string()手册中的以下几行:
MySQL只需要转义反斜杠和用于引用查询中字符串的引号字符。mysql_real_escape_string()引用其他字符以使它们更容易在日志文件中读取。
MySQL中的SQL注入不能仅使用这些特殊字符:b\0
\n
\r
\t
\Z
。
然而,字符串文本手册说明了以下内容,但指定(或不指定)的原因与SQL注入无关:
如果要将二进制数据插入字符串列(如BLOB列),则应使用转义序列表示某些字符。反斜杠(\)和用于引用字符串的引号字符必须转义。在某些客户端环境中,可能还需要转义NUL或Control Z。如果未转义,mysql客户端会截断包含NUL字符的带引号字符串,如果未转义,则Windows上的Control Z可能会作为文件结尾。
此外,在一个简单的测试中,无论上述特殊字符是否转义,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' ) );
只想确认Oracle SQL中需要转义哪些字符才能避免SQL注入?到目前为止,我只发现这篇文章似乎回答了我的问题:https://ss64.com/ora/syntax-escape.html.然而,正如我所听说的,amphora“@”字符也需要转义,因此,我认为上面的文章中有不完整的需要转义的字符列表。如果有人能告诉我Oracle SQL中需要转义的字符的完整列表,我将不胜感激。
问题内容: 我正在使用MySQL API的功能 根据文档,它转义以下字符: 现在,我查看了OWASP.org的ESAPI安全库,并在Python端口中包含以下代码(http://code.google.com/p/owasp- esapi-python/source/browse/esapi/codecs/mysql。 py ): 现在,我想知道是否真的需要转义所有这些字符。我知道为什么%和_在那
我是不是忽略了什么?任何帮助,提示或其他资源将非常感谢。我搜索了无数的谷歌列表,但无法解决这个问题。
当req.query.filter是一个没有空格的字符串时,比如'education'······这管用。当我试图找到一个有空格的列名时,比如'this havs空格',这个查询不起作用。我怎么才能修好这个?
这个答案说,验证用于确保Java字节码“遵循Java语言规则以确保安全”。 如果未执行此验证,将允许运行不安全的字节码。这会导致什么问题? 在什么情况下禁用字节码验证是可以接受的?
在最新版本的JavaSpecialists时事通讯中,作者提到了一段在Java中不可编译的代码 尝试编译它,你会得到一个错误,比如: 为什么一段等价的C#代码没有显示出这样的问题?