【发布时间】:2021-12-02 18:38:42
【问题描述】:
我想加深对可能存在的 SQL 注入攻击的了解。我知道参数化完全避免了 SQL 注入风险,因此应该在任何地方应用。但是,当有人问我如何利用它时,我希望得到一个答案。
我知道基本的 SQL 注入攻击是如何工作的。例如,一个网站有一个页面website.com/users/{id},其中 id 是用户的主键。如果我们完全信任输入并简单地将 id 参数传递给正在执行的查询,这可能会产生可怕的后果。对于website.com/users/1,查询变为SELECT * FROM [User] WHERE [Id] = 1。但是,在website.com/users/1;DROP TABLE User 的情况下,查询变为SELECT * FROM [User] WHERE [Id] = 1;DROP TABLE User,导致结果很糟糕。
但是,我读到的几乎所有 SQL 注入攻击都依赖于在注入之前出现的 WHERE 子句。几乎总是,注入以;Injected statement-- 的某种形式起作用。
我的问题是,如果给定如下查询,是否也可以执行 SQL 注入攻击?或者从更广泛的意义上说:是否必须编译整个语句才能进行 SQL 注入攻击,或者语句中的任何错误都会导致攻击失败?如果每个 DBMS 的答案不同,请指定 DBMS。
在下面的查询中,注入应该发生在CHARINDEX('input', [Name]) > 0 中,其中input 是从用户的输入中复制而来的。
SELECT
*
FROM (
SELECT TOP 10
*
FROM
[User]
WHERE
CHARINDEX('input', [Name]) > 0
) AS [User]
LEFT JOIN
[Setting] ON [Setting].[UserId] = [User].[Id]
我最了解的是下面的查询,但它返回的错误 Missing end comment mark '*/' 似乎完全阻止了任何攻击。
SELECT
*
FROM (
SELECT TOP 10
*
FROM
[User]
WHERE
CHARINDEX('input', '') > 0) AS [User];DROP TABLE [NonExistentTable]/*, [Name]) > 0
) AS [User]
LEFT JOIN
[Setting] ON [Setting].[UserId] = [User].[Id]
【问题讨论】:
-
在您的查询中,字符串连接发生在哪里?这就是注入 SQL 的地方。
-
如果您使用参数,那么它会在执行查询之前阻塞(
1;DROP..不是整数值),或者只是将“DROP”视为值的一部分,而不是命令 -
@SalmanA 让我看看如何才能更清楚。但是应该发生注入的部分是 CHARINDEX('input'.
标签: sql sql-injection