存储过程中的SQL注入


SQL Injection within a stored procedure?

我发现在代码的某个地方字符串没有被正确转义。我一直在尝试看看它是否可以被利用(别担心,我最终会转义它或使用准备好的语句,这只是一个学习经验)。

这是使用mysqli->query()函数;

查询在PHP中是这样生成的:

$Query = "CALL some_proc(".$_SomeID.",'".$_UnescapedString."')";

通过输入$_UnescapedString作为test'); DROP TABLE SomeTable; --,我得到查询:

CALL some_proc(1, 'test'); DROP TABLE SomeTable; -- ')

此查询已成功运行,但似乎没有运行第二个查询。我通过在第二个查询中放入无效的SQL来测试这一点,没有出现错误。我假设这意味着mysqli足够聪明,只执行单个查询?

现在我的问题是,我能以某种方式注入SQL到存储过程本身?步骤如下:

BEGIN
   SELECT COUNT(*) AS SomeCount
   FROM DataTable
   WHERE DataTable.SomeID = _SomeID
   AND DataTable.SomeValue LIKE CONCAT('%',_UnescapedString,'%');
END

我尝试了各种SQL,如test','%')--,看看查询是否会正常进行,但它只改变存储过程调用,即:

CALL some_proc(1, 'test', '%')--');

是否可以将DROP TABLE命令转换为_UnescapedString ?

免责声明,我使用SQL Server而不是mySQL,但假设与存储过程中的参数有关的行为是相同的,并且假设_UnescapedString是输入参数,将DROP TABLE放在参数中看起来像这样:

SELECT COUNT(*) AS SomeValue
FROM DataTable
WHERE DataTable.SomeID = _SomeID
AND DataTable.SomeValue LIKE '%DROP TABLE%');

关于查询:

CALL some_proc(1, 'test'); DROP TABLE SomeTable; -- ')

也许DROP TABLE命令没有执行是因为您正在运行的用户帐户没有足够的权限来执行DDL语句?

限制从web服务器访问数据库的用户帐户的权限是限制SQL注入攻击可能造成的损害的一种方法。然而,这并不能阻止他们。