Is the following safe from SQL injection? The user would pass in a comma separated list of codes as a string (Ex. '1'
, '1,3'
, '1,2,3'
, etc). I read that SQL parameters protect against SQL injection.
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
It seems like someone could inject malicious code into @StatusCodes
, but what I've read, that's not the case, because using parameters will prevent that. Parameters can fail when using dynamic SQL statements and unsafe concatenation, but that's not what's happening here.
So my guess is that it's safe, however, I wasn't able to find anything specifically related IN clause and a string parameter inserted into the middle. Yes, I know there are other ways to pass in an array of ints, but this is a very convenient way to do it. But it has to be safe, of course, or I won't do this.
Thanks.
1条答案
按热度按时间tkclm6bt1#
What you are seeking to do won't allow any sql injection, but it also will not work the way you want.
Say you pass a value like
1,2,3
via@StatusCodes
.This will NOT result in the
ActionStatusCode IN (1,2,3)
expression you're hoping for. Rather, you have one varchar value, so what you end up with is more likeActionStatusCode IN ('1,2,3')
. The type mismatch means this probably won't even execute, and if it does execute it's only looking at1,2,3
as one contiguous string instead of three separate integers.To get around this, your options are a Table-Value Parameter (which I personally find awkward), using
String_Split()
to separate the values inside the procedure, or sending the values one at a time to a temp/session/shopping cart table or similar storage as the user selects them to use with a JOIN.Honestly, none of these options are particularly great. If it came down to it, I'd probably use
String_Split
, though I need to get more comfortable using a TVP from ADO.Net.