这个 MySQL 查询为何容易受到 SQL 注入攻击?

发布于 2024-07-09 12:52:09 字数 419 浏览 6 评论 0原文

在对上一个问题的评论中,有人说以下 sql 语句让我面临 sql 注入:

select
    ss.*,
    se.name as engine,
    ss.last_run_at + interval ss.refresh_frequency day as next_run_at,
    se.logo_name    
from 
    searches ss join search_engines se on ss.engine_id = se.id
where
    ss.user_id='.$user_id.'
group by ss.id
order by ss.project_id, ss.domain, ss.keywords

假设 $userid 变量已正确转义,这如何使我容易受到攻击,我能做什么做什么来修复它?

In a comment on a previous question, someone said that the following sql statement opens me up to sql injection:

select
    ss.*,
    se.name as engine,
    ss.last_run_at + interval ss.refresh_frequency day as next_run_at,
    se.logo_name    
from 
    searches ss join search_engines se on ss.engine_id = se.id
where
    ss.user_id='.$user_id.'
group by ss.id
order by ss.project_id, ss.domain, ss.keywords

Assuming that the $userid variable is properly escaped, how does this make me vulnerable, and what can I do to fix it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

神妖 2024-07-16 12:52:09

每个值得使用的 SQL 接口库都对绑定参数提供某种支持。 不要试图变得聪明,只要利用它即可。

你可能真的、真的认为/希望你已经正确地逃避了一些事情,但不值得花时间。

此外,一些数据库支持预准备语句缓存,因此正确使用也可以为您带来效率提升。

更简单、更安全、更快。

Every SQL interface library worth using has some kind of support for binding parameters. Don't try to be clever, just use it.

You may really, really think/hope you've escaped stuff properly, but it's just not worth the time you don't.

Also, several databases support prepared statement caching, so doing it right can also bring you efficiency gains.

Easier, safer, faster.

意中人 2024-07-16 12:52:09

假设它被正确逃脱,它不会让你变得脆弱。 问题是,正确地转义比乍一看要困难,并且每次执行这样的查询时,您都会谴责自己正确地转义。 如果可能,请避免所有这些麻烦并使用准备好的语句(或绑定参数或参数化查询)。 这个想法是允许数据访问库正确转义值。

例如,在 PHP 中,使用 mysqli

$db_connection = new mysqli("localhost", "user", "pass", "db");
$statement = $db_connection->prepare("SELECT thing FROM stuff WHERE id = ?");
$statement->bind_param("i", $user_id); //$user_id is an integer which goes 
                                       //in place of ?
$statement->execute();

Assuming it is properly escaped, it doesn't make you vulnerable. The thing is that escaping properly is harder than it looks at first sight, and you condemn yourself to escape properly every time you do a query like that. If possible, avoid all that trouble and use prepared statements (or binded parameters or parameterized queries). The idea is to allow the data access library to escape values properly.

For example, in PHP, using mysqli:

$db_connection = new mysqli("localhost", "user", "pass", "db");
$statement = $db_connection->prepare("SELECT thing FROM stuff WHERE id = ?");
$statement->bind_param("i", $user_id); //$user_id is an integer which goes 
                                       //in place of ?
$statement->execute();
可是我不能没有你 2024-07-16 12:52:09

如果 $user_id 被转义,那么您应该不会受到 SQL 注入的攻击。

在这种情况下,我还要确保 $user_id 是数字或整数(取决于所需的确切类型)。 您应始终将数据限制为最严格的类型。

If $user_id is escaped, then you should not be vulnerable to SQL Injection.

In this case, I would also ensure that the $user_id is numeric or an integer (depending on the exact type required). You should always limit the data to the most restrictive type you can.

衣神在巴黎 2024-07-16 12:52:09

如果它被正确转义和验证,那么就不会有问题。

当没有正确转义或验证时就会出现问题。 这可能是由于草率编码或疏忽造成的。

问题不在于特定实例,而在于模式。 这种模式使得 SQL 注入成为可能,而另一种模式则使其不可能。

If it is properly escaped and validated, then you don't have a problem.

The problem arises when it is not properly escaped or validated. This could occur by sloppy coding or an oversight.

The problem is not with particular instances, but with the pattern. This pattern makes SQL injection possible, while the other pattern makes it impossible.

天冷不及心凉 2024-07-16 12:52:09

所有答案都很好而且正确,但我觉得我需要补充一点,prepare/execute 范例也不是唯一解决方案。 您应该有一个数据库抽象层,而不是直接使用库函数,这样的层是显式转义字符串参数的好地方,无论您是否让prepare这样做,或者你自己做。

All answers are good and right, but I feel I need to add that the prepare/execute paradigm is not the only solution, either. You should have a database abstraction layer, rather than using the library functions directly and such a layer is a good place to explicitly escape string parameters, whether you let prepare do it, or you do it yourself.

淡水深流 2024-07-16 12:52:09

我认为“正确逃脱”是这里的关键词。 在您的最后一个问题中,我假设您的代码是从您的产品中复制粘贴的代码,并且由于您询问了有关三个表连接的问题,我还假设您没有进行正确的转义,因此我对 SQL 注入攻击发表了评论。

为了回答您的问题,正如这里很多人所描述的那样,如果变量已被“正确转义”,那么您就没有问题。 但为什么要这样做呢? 正如一些人指出的那样,有时正确逃脱并不是一件简单的事情。 PHP 中有一些模式和库使 SQL 注入变得不可能,为什么我们不直接使用它呢? (我还故意假设你的代码实际上是 PHP)。 Vinko Vrsalovic 答案可能会给你一些想法如何解决这个问题。

I think 'Properly Escaped' here is the keyword. In your last question, I'm making the assumption that your code is copy pasted from your production code, and since you asked question about three tables join, I also make the assumption that you didn't do proper escaping, hence my remark on SQL Injection attack.

To answer your question, as so many people here has described, IF the variable has been 'Properly Escaped', then you have no problem. But why trouble yourself by doing that? As some people have pointed out, sometimes Properly Escaping is not a straightforward thing to do. There are patterns and library in PHP that makes SQL Injection impossible, why don't we just use that? (I also deliberately make assumption that your code is in fact PHP). Vinko Vrsalovic answer may give you ideas on how to approach this problem.

蓝颜夕 2024-07-16 12:52:09

这样的声明实际上并不是一个问题,它是“安全的”,但是我不知道你是如何做到这一点的(API 堆栈上一级)。 如果 $user_id 使用字符串操作插入到语句中(就像让 Php 自动填写语句一样),那么它很危险。

如果使用绑定 API 进行了填写,那么您就可以开始了。

That statement as such isn't really a problem, its "safe", however I don't know how you are doing this (one level up on the API stack). If $user_id is getting inserted into the statement using string operations (like as if you are letting Php automatically fill out the statement) then its dangerous.

If its getting filled in using a binding API, then your ready to go.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文