将运算符作为存储过程中的参数传递,同时防止 SQL 注入的风险

S M*_*S M 0 sql sql-server sql-server-2014

我有以下动态查询,并希望传递一个运算符作为参数,但出现错误

@ageOperator 附近的语法不正确

另外,我想防止任何SQL注入。我可以像下面那样进行串联,但它会导致 SQL 注入。

@sWhere = ' WHERE AGE1 ' + @ageOperator + ''' + @age + '''
Run Code Online (Sandbox Code Playgroud)

先感谢您!

DECLARE @age INT, 
        @ageOperator VARCHAR(10), 
        @sSQL NVARCHAR(MAX), 
        @sWhere NVARCHAR(MAX)

SET @age = 21
SET @ageOperator = ' = '

SET @sWhere = ' WHERE AGE1 @ageOperator @age '

SET @sSQL = ' SELECT * FROM WEBPM_COPY.DBO.Test1111 ' + @sWhere 

EXEC sp_executesql @sSQL, N'@age INT, @ageOperator char(10)', @age, @ageOperator;
Run Code Online (Sandbox Code Playgroud)

Zoh*_*led 5

如果您希望执行此代码,则必须将运算符连接到@sWhere变量:

set @sWhere = ' WHERE AGE1 '+ @ageOperator +' @age ';
Run Code Online (Sandbox Code Playgroud)

然而,10 个字符就足够了'=1 or 1=1--'(正好 10 个字符),所以它并不是真正的 SQL 注入安全。

更好的实现是接受一组有限的运算符并将其列入白名单:

DECLARE @age INT, 
        @ageOperator VARCHAR(10), 
        @sSQL NVARCHAR(MAX), 
        @sWhere NVARCHAR(MAX);

SET @age = 21;
SET @ageOperator = ' = ';

IF @ageOperator NOT IN('=', '<=', '>=', '<>') 
    RAISERROR ('Invalid @ageOperator', -1, 1);  

SET @sWhere = ' WHERE AGE1 '+ @ageOperator +' @age ';

SET @sSQL = ' SELECT * FROM WEBPM_COPY.DBO.Test1111 ' + @sWhere ;

EXEC sp_executesql @sSQL, N'@age INT, @ageOperator char(10)', @age, @ageOperator;
Run Code Online (Sandbox Code Playgroud)