提问人:John 提问时间:4/7/2023 最后编辑:marc_sJohn 更新时间:4/7/2023 访问量:150
如果我在 IN 子句中使用 SQL 参数,这是否可以保护它免受 SQL 注入?
If I use SQL parameters in an IN clause, does that protect it against SQL injection?
问:
以下是否安全,不会进行 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 子句和插入中间的字符串参数。是的,我知道还有其他方法可以传入整数数组,但这是一种非常方便的方法。当然,它必须是安全的,否则我不会这样做。
谢谢。
答:
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
评论
IN ( @StatusCodes)
将等同于 ;包含逗号分隔的字符串不会被数据引擎分析为元组。= @StatusCodes
(n)varchar