存储过程安全性中的动态SQL

时间:2011-10-06 09:10:43

标签: sql security

我已经从地狱创建了SQL存储过程,并且所有输入参数都是为安全性而参数化的,但它的运行速度并不像我想的那样快,所以我想让它变得动态,因此效率更高一些。

我知道我可以将输入参数保存到我的存储过程中,然后在其中创建一个动态SQL语句,然后我可以传递存储过程的输入参数,但是有任何安全隐患我需要注意这样做的时候?我猜不是因为它只是另一组参数,它们应该被视为与传递给当前存储过程的参数相同。

显然,生成像这样的代码“WHERE OrderNo ='+ @orderno要求麻烦 - 我将在动态SQL中做'WHERE OrderNo = @orderno',但还有什么我需要注意的吗? Thx MH

PS - 在任何人建议之前,我无法使用LINQ或类似方法在客户端动态创建SQL - 所有(由于各种原因)必须在数据库级别包含和控制

2 个答案:

答案 0 :(得分:1)

有一种SQL注入形式,很多人在存储过程中执行动态SQL时都没有考虑: SQL截断攻击

通过SQL截断攻击,攻击者会注入长时间的文本,使得使用过的文本变量溢出并丢失部分查询。

This article提供了有关此内容的更多信息。

答案 1 :(得分:0)

如果您的参数始终是数据项,那么在传递给StoredProc 时,无论是在动态SQL中使用还是,一切都将保持安全。

如果您的任何StoredProc参数最终成为表或字段名称,因此构成DynamicSQL本身结构的一部分,则会引入新的风险:该参数可用于注入流氓SQL代码。

  • 为防止此类注入攻击,您应该始终验证任何此类参数。

如何执行此操作的一个示例是使用输入参数作为标记,而不是将其直接替换为DynamicSQL ...

SET @SQL = @SLQ + CASE targetTable WHEN '1'  THEN 'table1'
                                   WHEN 'tx' THEN 'tableX'
                  END

有些人建议您只需要在客户端应用程序上进行验证。但这意味着,如果有人能够直接执行你的SP,那么SP就成了一个攻击点。我总是喜欢在客户端和服务器上验证它们。


编辑效果

请注意,使用DynamicSQL并不总是性能提升的保证。如果使用参数化查询,则确实可以存储执行计划。但是,如果查询确实存在很大差异,您仍可能在编译SQL时遇到很大的开销。

还存在依赖性跟踪丢失的事实。不可能看到SP依赖哪些表,因为代码被隐藏为字符串。

我很少发现需要DynamicSQL。通常,复杂查询可以作为多个优化查询进行重组。或者可以重新构建数据以满足新的需求。甚至可以使用数据重新考虑数据和算法。有人甚至可以建议对DynamicSQL的依赖是另一个潜在问题的指标。

也许这不在你的问题范围内,但看到你所面对的实际谜题会很有趣;看看是否有人有任何替代方法。