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

时间:2008-11-25 04:28:24

标签: mysql security sql-injection

在对前一个问题的评论中,有人说下面的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变量被正确转义,这怎么会让我容易受到攻击,我该怎么做才能解决它?

7 个答案:

答案 0 :(得分:14)

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

你可能真的,真的认为/希望你已经正确地逃脱了东西,但是你不值得花时间。

此外,一些数据库支持预处理语句缓存,因此正确执行也可以提高效率。

更轻松,更安全,更快。

答案 1 :(得分:5)

假设它被正确转义,它不会让你容易受到攻击。事情是,正确逃避比第一眼看上去更难,并且每次进行这样的查询时,你都会谴责自己逃脱。如果可能,避免所有麻烦并使用预准备语句(或绑定参数或参数化查询)。我们的想法是允许数据访问库正确地转义值。

例如,在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();

答案 2 :(得分:1)

如果已正确转义并验证,那么您没有问题。

如果未正确转义或验证,则会出现问题。这可能是通过草率编码或疏忽造成的。

问题不在于特定情况,而在于模式。这种模式使SQL注入成为可能,而另一种模式使得它无法实现。

答案 3 :(得分:1)

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

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

答案 4 :(得分:1)

我认为'正确转义'是关键字。在你的last question中,我假设您的代码是从您的生产代码中复制粘贴的,并且由于您询问了有关三个表连接的问题,我还假设您没有进行适当的转义,因此我对SQL注入攻击的评论。

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

答案 5 :(得分:0)

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

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

答案 6 :(得分:0)

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