Suppose I’m querying a Sql Server DB for row count based on a LIKE comparison on a column whose value is supplied via windows form text input. Using parameters here is important due to possible user input leading to injection. Eventually I’m to execute member function ExecuteScalar() on an instantiated SqlCommand object I named cmd, but first I’ve to add the parameter. For example:
cmd.Parameters.AddWithValue("@param1", textBox1.Text);
Sql Server uses the special character % as a wildcard match for the LIKE comparison. What I wanted to do was allow the user to use * for wildcards instead. Hence, a simple replace:
textBox1.Text.Replace('*','%');
The problem is I run into issues with values containing special symbols % and _. One way to search for a literal % rather than use it as a wildcard is to enclose it in square brackets: [%].
So, now my replace has to become:
textBox1.Text.Replace("%","[%]").Replace("_","[_]").Replace('*','%');
Order is important here as well, since if the last Replace were made sooner the % would be treated incorrectly.
I’m not sure I’ve covered all my bases, are there other characters I need to worry about here? Does this really protect from injection? Is there some other preferred way of doing this?
An example query might be something like this:
SELECT COUNT(*) FROM [MyTable] WHERE [Column1] = @param1
Where MyTable is your table name, and Column1 is a valid column name within MyTable. We can assume that Column1 is some nvarchar type.
You shouldn’t really need anything else, but I’d make sure to test oddball things from user input. Some characters you haven’t accounted for have special meaning in
LIKE:Since you’re passing a parameter into the statement and not blindly appending the string, there should be little danger of injection, but you may want to try variations of user input such as:
Again, I’m not sure if you’re vulnerable because I can’t see the whole thing, but I do think it’s very easy to construct a variety of tests so that you know all of the potential outcomes with a wide sampling of potential inputs.
As @Bryan pointed out, certainly a good way to limit the risk is to connect using a login that has very explicit read-only permissions only on the objects you want them to be able to read. Then even if they do exploit some hole in your scaffolding, getting in doesn’t buy them much.