为什么这种 SQL 注入 'sleep' 攻击是一种有效的拒绝服务攻击?

Why is this SQL injection 'sleep' attack an effective denial of service?

今天,在管理客户的服务器时,我们的监控发现了一些缓慢的页面加载时间/其他问题。我在对此进行故障排除时注意到,以下查询在进程列表中并且似乎从未完成:

SELECT *
FROM   motorcycles
       LEFT JOIN motorcycle_year
              ON motorcycle_year.year_id = motorcycles.motorcycle_vyear
       LEFT JOIN motorcycle_make
              ON motorcycle_make.make_id = motorcycles.motorcycle_vmake
       LEFT JOIN dealers
              ON dealers.dealer_id = motorcycles.motorcycle_dealer
       LEFT JOIN motorcycle_subtype
              ON subtype_id = motorcycle_subtype
       LEFT JOIN fuel_type
              ON fuel_id = motorcycle_fuel
WHERE  motorcycle_id = -3885
        OR 1073 = Sleep(5)
           AND motorcycle_dealer = '91' 

一开始以为是客户端代码的bug,后来确定一定是SQL注入的结果,因为这部分:

WHERE  motorcycle_id = -3885
        OR 1073 = Sleep(5)
           AND motorcycle_dealer = '91' 

所以这似乎是某种 sql 注入 DOS 攻击。由于我不明白的技术原因,此查询似乎从未完成。

我试图通过测试 table 和一个简单的查询在更简单的上下文中重现它:

SELECT *
FROM   users
WHERE  id = -9000
        OR 1073 = Sleep(5)
           AND foo = 'bar'

但正如我所料,它在大约 5 秒内完成。那么为什么前一个查询永远不会完成呢?它与连接有关吗?出于纯粹的好奇心,我现在想了解这一点。

如果这更适合另一个堆栈交换论坛,请随时将问题迁移到那里。

编辑:为了清楚起见,如果我用类似但更明智的值替换,前一个查询(似乎是 DOS sql 注入)returns 几乎立即:

WHERE motorcycle_id =
1 AND motorcycle_dealer = '91';

我认为 SQL 注入攻击是恶意的。写得不好的 SQL 查询会有所不同。许多联接涉及更多 table 和更多操作。复杂的 where 子句的复制可能很快。如果其他 table 正在进行查询、备份、重建索引,它们可能执行缓慢。 where 子句在带有连接的 multi-table 查询中有不明确的列。您可能希望使用 table 别名来消除歧义。

所有事情都是不变的,使用数字等价测试的 where 子句应该比正则表达式(字符串等价测试)执行得更快。但现实世界比我们可以理论化的要复杂得多。考虑到连接的复杂性,sleep(5) 可能会在 where 子句中被调用更多次。这可以解释为什么用于隔离问题的复制迷你查询会在如此短的时间内完成。

不确定这里的礼节,但我只是想在 PM77-1 的评论的帮助下将此标记为已解决

基本上,SLEEP(5) 发生在每条记录上,因为必须为每条记录评估条件。在我的测试中table,我只有一条记录,所以我无法重现看似永无止境的查询。