如何防止这种类型的 SQL 注入攻击?

信息安全 sql注入 编码
2021-08-24 01:04:05

我们公司一直在使用多种工具(Veracode、Appscan 等)来验证我们的应用程序是否满足最低安全要求。我继承了一个有几个缺陷的遗留应用程序。我已经设法缓解了大部分漏洞,但是在修复下一个漏洞时遇到了麻烦,因为我根本不知道它在做什么。在我们的报告中,它似乎正在将我们的 POST 变量之一更改为

25%27+having+1%3D1--+

这是什么以及它有效地做什么?我能做些什么来防止这种类型的攻击?

3个回答

当这个字符串从它的 url 编码形式解码时,它变成以下内容:

25' having 1=1--

该字符串按原样放置到例如以下 (PHP) 数据库查询函数中时:

mysql_query("SELECT * FROM users WHERE username = '$username'");

变成这样:

mysql_query("SELECT * FROM users WHERE username = '25' having 1=1--'");

请注意,%27 (') 会从 WHERE 子句中的参数中断,并继续语句的可执行部分。1=1 之后的 -- 使语句的其余部分成为未执行的注释。

SQL 中的 HAVING 语句应该在使用 GROUP BY 运算符的查询中使用,并且应该在不使用的查询中失败。我的猜测是,该字符串仅用于检查是否存在未处理的变量,该变量会放入已执行的查询中。

为了防止这种类型的攻击,我建议使用良好的输入清理功能或参数化查询。这取决于所讨论的编程环境。

补充:在 SQL 注入查询中正常使用 1=1 是为了返回所有行,使任何其他 WHERE 条件无效。一个示例输入可能是:

a' OR 1=1 --

在查询中作为 $password 参数插入时,例如:

SELECT * FROM users WHERE username = '$username' AND password = '$password'

语句变为:

SELECT * FROM users WHERE username = 'mark' AND password = 'a' OR 1=1 --

结果数据集将包括“用户”表中的所有条目,因为 1=1 始终为真。

你所看到的是一个相当标准的 SQL 注入攻击向量。如果应用程序没有正确处理输入,它添加的代码可以修改 SQL 语句(但我猜你从标题中解决了这个问题)。NGS/NCC在这篇论文中提到了这个向量的问题有一个很好的描述。

在缓解问题方面,您需要确保对应用程序的输入进行了适当的验证或转义,以便它无法修改对数据库的底层 SQL 查询。

OWASP SQL Injection Cheetsheet是一个很好的起点

参数化查询的替代方法是转义输入。如何正确执行此操作将取决于您的平台和数据库。例如,在 PHP 和 mysql 数据库上使用 mysql_real_escape_string()。此外,如果这样做,您必须始终在 SQL 中使用单引号,即使是数字也是如此。

您可能认为您可以只替换字符串中的单引号以使其安全,但这还不够。单引号可以用其他方式表示。更多细节在这里:多字节字符利用 - PHP/MySQL