exec(sql) 的安全替代方案

Ban*_*San 4 security sql-server sql-injection dynamic-sql t-sql

我发现exec(sql)代码中隐藏了一些语句。它们存在是有充分理由的,因为这些语句不能直接编写,但它们是一个明显的攻击媒介。

有没有安全的替代品exec(some sql)?将正确参数化的东西,包括语句中的表名?

Aar*_*and 9

对于某些类型的参数化,使用EXEC()或并不重要sp_executesql,因为有些东西无论如何都无法参数化。例如,您在评论中表示(请更新您的问题以更具体地了解您的要求!)您正在参数化表名,但是这些不能被参数化,因为它们需要从字面上表达到 SQL Server(它不能将其标记化并在运行时交换)。

为了保护自己免受表名漏洞的影响,您可以像这样轻松地保护自己:

DECLARE @tablename sysname; -- pretend this is a parameter
SET @tablename = N'this_is_not_a_table';

-- in procedure body:
IF NOT EXISTS (SELECT 1 FROM sys.tables WHERE name = @tablename)
BEGIN
  RAISERROR(N'Table does not exist.', 1, 11);
  RETURN;
END
SET @sql = N'SELECT ... FROM dbo.' + QUOTENAME(@tablename) + ...;
-- EXEC(@sql) or EXEC sys.sp_executesql @sql
Run Code Online (Sandbox Code Playgroud)

现在,我更喜欢使用sp_executesqlalways,部分原因是它提倡使用强类型参数(避免 SQL 注入问题以及双单引号问题),但也因为在某些情况下,您将为可参数化和不可参数化的值传递参数(是的,我编造了这些话)。更多信息:

现在,您唯一需要担心的是是否有人能够创建表并且可以创建名为的表sys.objects; DROP TABLE foo; --- 但是如果您有一个您不信任的人但有能力在您的数据库中创建表...

  • 如果您在该表上使用 quotename,我认为即使使用像 drop 这样的名称也是安全的。 (2认同)