MySQL是否具有针对基于URL的攻击的内置注入攻击防护?

时间:2019-02-16 16:31:06

标签: php mysql database security sql-injection

edit-不应将其标记为重复项。问题不在于如何防止SQL注入攻击(我已经在其他地方使用了准备好的语句),而是与MySQL为何杀死一个恶意注入的查询有关。


我正在测试具有连接的MySQL数据库的Web应用程序,特别是寻找潜在的SQL注入问题,并想知道在这种特定情况下如何防止此类攻击。

一个页面根据唯一的ID号从数据库中加载一个人的信息,该ID号可通过该页面的URL看到。显然,这本身就是一个问题-我可以将ID从“?id = 2”更改为“?id = 3”以从数据库中加载新记录-但我更关心的问题是此刻是基于URL的攻击,目的是在预期查询的顶部执行“不良”查询。

预期查询如下所示:... where person.ID="10" and person.ID = notes.ID and ...

通过更改URL,我可以关闭正在寻找ID的参数,并执行另一个潜在的恶意查询,如下所示:

... ?id=10"; drop table person; select * from notes where ID=" ... 

这将导致执行以下查询:

... select * from person, notes where id="10"; drop table person; select * from notes where ID="" and ...

我已经能够获取此恶意查询集,以将其打印(回显)到我的网页上,因此我知道这是一个漏洞。但是,当我尝试在MySQL中执行此确切查询时,它会挂起几秒钟,然后完全退出MySQL,并显示响应“杀死”,没有进一步的解释。

那么,我的问题是什么导致MySQL终止了该恶意查询并退出?这似乎是一项安全功能,但我不知道会是什么-那些查询本身就很好。如果有人遇到过类似情况,我还会对除“杀死”之外缺少错误消息感到困惑。

1 个答案:

答案 0 :(得分:0)

MySQL对您显示的情况的唯一保护是默认情况下,MySQL的查询接口不会执行多个语句。用;分隔语句只会导致语法错误。

但是,多查询是一个选项,并且取决于客户端,该选项可能已启用。

PDO默认情况下启用多查询。我可以运行以下命令,它将插入两行:

$pdo->query("insert into foo set id = 1; insert into foo set id = 2");

但是,如果尝试使用预处理语句(禁用模拟的prepare),它将失败:

$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

$stmt = $pdo->prepare("insert into foo set id = ?; insert into foo set id = ?");

如果启用了例外,则会引发异常:

  

PHP致命错误:未被捕获的PDOException:SQLSTATE [42000]:语法错误或访问冲突:1064您的SQL语法有错误;请参阅附录A。检查与您的MySQL服务器版本相对应的手册以获取正确的语法,以在“插入foo set id =?中插入”附近使用在第1行

Mysqli仅对使用mysqli_multi_query()函数执行的查询启用多查询。因此,如果您在代码中未使用multi_query(),则很安全。

此外,如果您确实使用查询参数(我看到您的评论中确实使用了查询参数),那么您也很安全,因为即使该参数包含任何欺骗查询的尝试,它也不会起作用。

使用准备好的语句时,参数不会简单地连接到SQL查询中。这是许多开发人员的误解。

将参数与SQL语法分开,直到之后解析SQL。然后,在MySQL执行查询时组合参数,但是对于任何尝试进行SQL注入的用户来说,修改查询的解析方式为时已晚。

这就是为什么查询参数是一种保护应用程序免受SQL注入的好方法。