如果我在 IN 子句中使用 SQL 参数,这是否可以保护它免受 SQL 注入?

If I use SQL parameters in an IN clause, does that protect it against SQL injection?

提问人:John 提问时间:4/7/2023 最后编辑:marc_sJohn 更新时间:4/7/2023 访问量:150

问:

以下是否安全,不会进行 SQL 注入?用户将以逗号分隔的代码列表作为字符串(例如,、、等)传递。我读到SQL参数可以防止SQL注入。'1''1,3''1,2,3'

CREATE PROCEDURE CurrentActions   
    @StatusCodes nvarchar(100)   -- 0 = Active, 1 = Completed, 2 = On Hold
AS   
    SELECT ActionId, ActionName, ActionStatusCode, Comments  
    FROM Action
    WHERE ActionStatusCode IN (@StatusCodes)
GO

似乎有人可以将恶意代码注入 ,但我所读到的并非如此,因为使用参数可以防止这种情况发生。使用动态 SQL 语句和不安全的串联时,参数可能会失败,但这不是这里发生的情况。@StatusCodes

所以我的猜测是安全的,但是,我找不到任何特别相关的 IN 子句和插入中间的字符串参数。是的,我知道还有其他方法可以传入整数数组,但这是一种非常方便的方法。当然,它必须是安全的,否则我不会这样做。

谢谢。

sql-server 存储过程 sql 注入

评论

5赞 Serg 4/7/2023
以这种方式,您最终会得到 IN 处的单个字符串值。考虑使用科技券
3赞 Thom A 4/7/2023
IN ( @StatusCodes)将等同于 ;包含逗号分隔的字符串不会被数据引擎分析为元组。= @StatusCodes(n)varchar

答:

2赞 Joel Coehoorn 4/7/2023 #1

你要做的事情不允许任何SQL注入,但它也不会按照你想要的方式工作

假设您传递了一个类似 via 的值。1,2,3@StatusCodes

会导致你所希望的表情。相反,你有一个 varchar 值,所以你最终得到的更像是 .类型不匹配意味着它甚至可能不会执行,如果它确实执行,它只会被视为一个连续的字符串,而不是三个单独的整数。ActionStatusCode IN (1,2,3)ActionStatusCode IN ('1,2,3')1,2,3


为了解决这个问题,您的选项是表值参数(我个人觉得很尴尬),使用 String_Split() 分隔过程中的值,或者一次将一个值发送到临时/会话/购物车表或类似的存储,因为用户选择它们与 JOIN 一起使用。

老实说,这些选项不是特别好。如果归根结底,我可能会使用 ,尽管我需要更习惯使用 ADO.Net 的 TVP。String_Split