【发布时间】:2019-09-07 17:09:17
【问题描述】:
我在 SQL Server 中有一个存储过程,它获取一个 XML 作为输入参数。在这个 XML 中定义了 - 应该使用哪些参数值执行哪些存储过程。并根据该存储过程使用动态 SQL 和sp_executesql 执行所需的存储过程。
问题是参数的值容易受到 SQL 注入的影响。
我尝试过使用这样的类型化参数:
EXEC sys.sp_executesql
@stmt = @sql,
@params = N'@Username SYSNAME, @HireDate DATE',
@UserName = @Username, @HireDate = @HireDate;
但在我的情况下它并没有真正起作用,因为我不知道将执行带有什么参数的程序。参数的数量可能会有所不同,其中一些是可选的/具有默认值等。我能得到的只是参数的名称作为字符串:(
在对输入的 XML 进行一些解析之后,SQL 查询就这样构建和执行了
declare @params nvarchar(max);
select @params = coalesce(@params + N', ', N' ') + r.attrName + N' = ' + iif(p.isNumericType = 1, r.Value, '''' + r.Value /*cast(r.Value as nvarchar(max))*/ + '''') --+ r.Value
from dbo.#ruleConfig r
left join @spParams p on p.paramName = r.attrName -- datatype of a parameter from information_schema.parameters
declare @sql nvarchar(max) = (select @procName + isnull(@params, N''));
exec dbo.sp_executesql @sql
@sql 的值可能类似于:
'core.GetUser @LogonName = 'myDomain\myLogon''
但也可以是这样的:
'core.GetUser @fullLogonName = 'myDomain\myLogon;'WAITFOR DELAY '0:0:20';--'' and that's the problem.
【问题讨论】:
-
In this XML is defined - what store procedure with which parameters values should be executed.为什么?为什么 database 解析这个字符串,而不是让客户端正确调用存储过程?那是问题的根源,而不是sp_executesql -
该字符串,无论是否可以解析为 XML,本身都容易受到 SQL 注入和转换错误的影响。它也比使用 ADO.NET、ODBC 或您的语言使用的任何协议正确调用数据库大数百倍。
-
“但在我的情况下它并没有真正起作用,因为我不知道会执行什么程序和什么参数。” 然后你可以建立一个动态的动态语句(不理想,但我已经看到了),或者传递所有参数,无论它们是否会在动态语句中使用。
EXEC sp_executesql N'SELECT 1 AS one;',N'@i int', @i = @i;不会出错,即使@i从未在“动态”查询中使用过。不过,我们这里没有任何信息,真的,无法给出完整的答案。 -
我认为这不可能保证安全。如果您不能信任您的用户,请不要这样做。将您的 XML 解析为单个局部变量,并在常规数据库语句中仅使用这些局部变量。
标签: sql-server tsql sql-injection dynamic-sql