【问题标题】:sp_execute SQL vs execsp_executeSQL 与 exec
【发布时间】:2013-01-07 15:45:26
【问题描述】:

正如我在以下博客中所读到的......

http://www.sommarskog.se/dynamic_sql.html

动态 sql 是不安全的,这就是我们有 sp_execute SQL 的原因。

请问,有什么方法可以让 sp_execute 运行这样的程序...

declare @QueryMain as varchar(8000)
declare @QueryBody as varchar(8000)
declare @QueryWhere as varchar(8000)

set @QueryMain = <8000 charactes>
set @QueryBody = <8000 characters>
set @QueryWhere = <8000 characters>

exec (@queryMain+@QueryBody+@QueryWhere)

这会运行,但正如我在文章中读到的那样,不建议这样做......但我想知道是否有另一种方式来运行这种查询......我试图合并 3 个变量到 ntext 但它没有工作,顺便说一句......上面的示例查询将在查询中有其他变量,可能是日期,用户 ID,任何东西!

我正在使用 sql server 2000 顺便说一句...正如我用谷歌搜索的那样,我没有发现如何为 sql server 2000 操作大字符串的结果,但我有 SQLi 攻击的这种后果。

【问题讨论】:

  • 为什么要运行这种查询?您将始终拥有实际的 SQL 语句,因为您正在构建它。您是否试图通过一段代码来运行它?
  • @twoleggedhorse 因为我将每个 sql 脚本从系统迁移到存储过程,经过我的测试,sql 脚本容易受到 sql 注入的影响。他们是我们过去程序员开发的遗留系统,却忽略了这种威胁的风险。

标签: sql tsql stored-procedures dynamic sql-server-2000


【解决方案1】:

如果你问是否可以这样做:

EXEC sp_executesql @QueryMain + @QueryBody + @QueryWhere;

不,您不能将表达式或公式作为参数值。但你为什么需要?解决方法很简单,只需将它们附加到一个中间变量中(这应该是NVARCHAR(MAX),而不是NTEXT,后者已被弃用且对局部变量无效):

DECLARE @sql NVARCHAR(MAX);

...

SET @sql = @QueryMain + @QueryBody + @QueryWhere;

EXEC sp_executesql @sql;

实际上所有这些变量都应该是NVARCHAR

this post for some more on EXEC vs. sp_executesql

【讨论】:

  • @Aaron_bertrand 我没有使用 nvarchar(max) 的原因是因为我们只有 sql server 2000,而且这个版本还不支持 nvarchar(max),我正在迁移每个 sql 脚本从系统嵌入到存储过程,降低sql注入风险
  • @Joshua 抱歉,我错过了 SQL Server 2000 标记。但是我认为你给自己一种虚假的安全感......为什么你认为使用 sp_executesql 执行一堆未经验证的文本会比使用 EXEC 更安全? sp_executesql 更安全的原因是它促进了强类型参数的使用,而不是因为它神奇地阻止了注入本身。您不打算以有助于恕我直言的方式使用它,所以请继续使用 EXEC。
  • @Aaron_bertrand 谢谢先生的澄清,我真的很想了解更多。谢谢你的知识先生!
猜你喜欢
  • 2010-10-07
  • 1970-01-01
  • 2013-01-21
  • 2023-03-25
  • 2015-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多