当前位置: 首页 > 知识库问答 >
问题:

哪些字符实际上能够导致MySQL中的SQL注入?

闾丘文昌
2023-03-14

我们都知道,我们应该使用准备好的语句或适当的替换/格式化规则,以防止sql注入到我们的应用程序中。

然而,在查看MySQL的字符文本列表时,我注意到它包括以下字符:

  • ASCII NUL(0x00)字符
  • 一个单引号(')字符
  • 双引号()字符
  • 一个退格字符
  • \n换行符(换行符)
  • \r回车符
  • 制表符
  • ASCII 26(CtrlZ)。见下表注释
  • 反斜杠字符
  • 一个字符
  • 一个字符

现在,虽然需要对% 字符进行转义,以防止向LIKE语句中注入不需要的通配符,而 '(单引号),\(反斜杠),和(双引号)都需要转义,以防止任意SQL的注入-如果未转义这些字符中的任何一个,是否会直接导致SQL注入漏洞,否则就不会存在?是否有人有任何此类漏洞的真实示例

假设我们正在构建查询,如下所示:

SELECT * FROM users WHERE username='$user'

如果唯一未转义的字符文本是允许向该查询中注入任意SQL的\b(backspace)、\0(NUL)、\n(newline)、\r(linefeed)、\t(tab)或\Z(Ctrl>\kbd>Z),那么是否有任何值用于$user(用户)>?


共有2个答案

辛承
2023-03-14

2020年起的强制性增编:

你必须使用事先准备好的语句,忘记逃跑、“危险人物”或其他任何事情。

使用参数化查询被认为是防止SQL注入的唯一正确方法,原因如下:

哪些字符实际上能够导致mysql中的SQL注入

导致SQL注入的不是“字符”。但格式不正确。根据具体情况,任何角色都可能是“危险的”或绝对无害的。将保护限制在某个子集是一种危险的错觉,它迟早会导致SQL注入。

你的问题中有两个错误的陈述导致了你的困惑:

  1. 我们都知道我们应该使用...适当的替换规则来防止我们的应用程序中的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子句中,“%”字符是否会导致除额外结果以外的任何结果。

堵雅健
2023-03-14
匿名用户

考虑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#代码没有显示出这样的问题?