我们公司一直在使用多种工具(Veracode、Appscan 等)来验证我们的应用程序是否满足最低安全要求。我继承了一个有几个缺陷的遗留应用程序。我已经设法缓解了大部分漏洞,但是在修复下一个漏洞时遇到了麻烦,因为我根本不知道它在做什么。在我们的报告中,它似乎正在将我们的 POST 变量之一更改为
25%27+having+1%3D1--+
这是什么以及它有效地做什么?我能做些什么来防止这种类型的攻击?
我们公司一直在使用多种工具(Veracode、Appscan 等)来验证我们的应用程序是否满足最低安全要求。我继承了一个有几个缺陷的遗留应用程序。我已经设法缓解了大部分漏洞,但是在修复下一个漏洞时遇到了麻烦,因为我根本不知道它在做什么。在我们的报告中,它似乎正在将我们的 POST 变量之一更改为
25%27+having+1%3D1--+
这是什么以及它有效地做什么?我能做些什么来防止这种类型的攻击?
当这个字符串从它的 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