SQL Server - 在处理传递给存储过程的动态 WHERE 子句时如何防止 SQL 注入

Nan*_*a A 4 security sql-server parameter

鉴于以下存储过程,我能否在提供的附加WHERE条件下防止 SQL 注入?

CREATE PROCEDURE [dbo].[ProtectDynamicWhereClause]
   (@TableName varchar(50),
    @OldestRecordDate varchar(15),
    @WhereCondition varchar(250) = NULL)
AS
BEGIN
    -- Protect the table name from SQL Injection.
    DECLARE @TableNameClean varchar(150) = QUOTENAME(@TableName)

    DECLARE @sql nvarchar(4000)
    SET @sql = 
            N'
            SELECT * FROM ' + 'dbo.' + @TableNameClean
            + ' WHERE EntryAge > DATEDIFF(year, @OldestRecordDate, GETDATE()) '

    IF (@WhereCondition IS NOT NULL)
    BEGIN
        SET @sql = @sql + ' AND ' + @WhereCondition
    END               

    EXEC  sp_executesql @sql, N'@TableNameClean varchar(50), @OldestRecordDate varchar(15)', 
                                @TableNameClean = @TableNameClean, @OldestRecordDate = @OldestRecordDate
END

EXEC ProtectDynamicWhereClause @TableName='CustomerTbl', @OldestRecordDate = '2012-01-01', @WhereCondition = 'CustomerName LIKE ''%Smith%'''
EXEC ProtectDynamicWhereClause @TableName='ProductTbl', @OldestRecordDate = '2010-01-01', @WhereCondition = 'ProductId IN (123, 345, 567)'
Run Code Online (Sandbox Code Playgroud)

@WhereCondition如图所示,当实际作为参数传入存储过程时,您能否告诉我如何在此语句中防止 SQL 注入?

SET @sql = @sql + ' AND ' + @WhereCondition
Run Code Online (Sandbox Code Playgroud)

谢谢你。

Aar*_*and 7

您只是不要以用户可以传入结构化WHERE子句的方式编写它。这是灾难的秘诀,我敢打赌,至少有一半被 SQL 注入利用的公司认为他们可以通过检查关键字输入、去除分号和注释等来保护自己。他们没有,而且无论您尝试手动编写什么保护,总会有办法解决。

不要偷懒。编写它以便用户从下拉列表中选择可能的列和操作,并且只将参数值输入到自由文本中。然后,您使用已知存在的列强类型参数构建动态 SQL ,这些参数只能被视为如此,而不仅仅是将您的查询附加到某人在网页上的表单字段中键入的内容并盲目执行它。

当然,这个表中没有 8,000 列,用户可以添加的子句排列数量并不详尽。您始终可以在逻辑上将其限制为 5 或 10 个子句,以便您没有 GB 长的 WHERE 子句。

处理动态 SQL 和灵活的 WHERE 子句的一些建设性想法:

在这里这里有关于我的“厨房水槽”解决方案的视频以及关于它的博客文章

我谈论厨房水槽程序的其他答案: