简体   繁体   English

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

[英]Does MySQL have built-in injection attack protections against URL-based attacks?

edit - this shouldn't be marked as a duplicate. 编辑-不应将其标记为重复项。 The question isn't how to prevent SQL injection attacks (I'm already using prepared statements elsewhere), it's related to why MySQL is killing a maliciously-injected query. 问题不在于如何防止SQL注入攻击(我已经在其他地方使用了准备好的语句),而是与MySQL为何杀死一个恶意注入的查询有关。


I'm testing out a web app with a connected MySQL database, specifically looking for potential SQL injection concerns and wondering how to prevent such attacks in this specific case. 我正在测试一个具有连接的MySQL数据库的Web应用程序,特别是寻找潜在的SQL注入问题,并想知道在这种特定情况下如何防止此类攻击。

One page loads a person's information from the database based on a unique ID number, which is visible through the page's URL. 一页基于唯一的ID号从数据库中加载一个人的信息,该ID号可通过该页的URL看到。 Obviously, this is a concern in its own right - I could simply change the ID from "?id=2" to "?id=3" to load a new record from the database - but the issue I'm more concerned with at the moment is a URL-based attack to execute a "bad" query on top of the intended query. 显然,这本身就是一个问题-我可以简单地将ID从“?id = 2”更改为“?id = 3”以从数据库加载新记录-但是我更关心的问题是此刻是基于URL的攻击,目的是在预期查询之上执行“不良”查询。

The intended query looks something like this: ... where person.ID="10" and person.ID = notes.ID and ... 预期的查询如下所示: ... where person.ID="10" and person.ID = notes.ID and ...

By changing the URL, I'm able to close the parameter that's looking for an ID and execute another, potentially malicious query, like this: 通过更改URL,我可以关闭正在寻找ID的参数,并执行另一个潜在的恶意查询,如下所示:

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

which would cause the following queries to be executed: 这将导致执行以下查询:

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

I've been able to get this malicious set of queries to print (echo) to my webpage, so I know it's a vulnerability. 我已经能够获取这组恶意查询,以将其打印(回显)到我的网页上,因此我知道这是一个漏洞。 However, when I try to execute this exact query in MySQL, it hangs for several seconds before exiting MySQL completely with the response "Killed" and no further explanation. 但是,当我尝试在MySQL中执行此确切查询时,它会挂起几秒钟,然后完全退出MySQL,并显示响应“杀死”,没有进一步的解释。

My question, then, is what's causing MySQL to kill this malicious query and exit? 那么,我的问题是什么导致MySQL终止了该恶意查询并退出? This seems like a security feature, but I don't know what it'd be - those queries are perfectly fine on their own. 这似乎是一项安全功能,但我不知道会是什么-那些查询本身就很好。 I'm also confused by the lack of error message beyond "Killed" if anyone has come across a similar situation. 如果有人遇到过类似情况,我还会对缺少“杀”之外的错误消息感到困惑。

The only protection MySQL has against the case you show is that by default, MySQL's query interface doesn't execute multiple statements. MySQL对您显示的情况的唯一保护是默认情况下,MySQL的查询接口不会执行多个语句。 Separating statements by ; 用分隔语句; will only result in a syntax error. 只会导致语法错误。

However, multi-query is an option, and depending on the client, the option may have been enabled. 但是,多重查询是一个选项,并且取决于客户端,该选项可能已启用。

PDO enables multi-query by default. PDO默认情况下启用多查询。 I can run the following and it will insert two rows: 我可以运行以下命令,它将插入两行:

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

However, if you try to use prepared statements (disabling emulated prepare), it fails: 但是,如果尝试使用准备好的语句(禁用模拟的prepare),它将失败:

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

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

This throws an exception if you enabled exceptions: 如果启用了异常,则会引发异常:

PHP Fatal error: Uncaught PDOException: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; PHP致命错误:未被捕获的PDOException:SQLSTATE [42000]:语法错误或访问冲突:1064 check the manual that corresponds to your MySQL server version for the right syntax to use near 'insert into foo set id = ?' 检查与您的MySQL服务器版本相对应的手册以获取正确的语法,以在“插入foo set id =?中插入”附近使用 at line 1 在第1行

Mysqli enables multi-query only for queries you execute with the mysqli_multi_query() function. Mysqli仅对使用mysqli_multi_query()函数执行的查询启用多查询。 So if you don't use multi_query() in your code, you're safe. 因此,如果您在代码中未使用multi_query(),则很安全。

Furthermore, if you do use query parameters (I saw your comment that you do use query parameters), you're also safe, because even if the parameter were to contain any attempt to fool the query, it won't work. 此外,如果您确实使用查询参数(我看到您的评论中确实使用了查询参数),那么您也很安全,因为即使参数包含任何欺骗查询的尝试,它也不会起作用。

Parameters are not simply concatenated into the SQL query when you use prepared statements. 使用准备好的语句时,不能将参数简单地串联到SQL查询中。 This is a misunderstanding many developers have. 这是许多开发人员的误解。

Parameters are kept separate from the SQL syntax until after the SQL is parsed. 解析SQL之前参数与SQL语法保持分开。 Then the parameter is combined as MySQL executes the query, but it's too late for any attempted SQL injection to modify the way the query will be parsed. 然后在MySQL执行查询时组合参数,但是对于任何尝试的SQL注入修改查询解析方式为时已晚。

That's why query parameters are a good method of protecting your app from SQL injection. 这就是为什么查询参数是保护您的应用程序免受SQL注入攻击的好方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM