Dynamic SQL and SQL injection

When I wrote about the catch-all queries, someone asked why the dynamic SQL that I offered wasn’t vulnerable to SQL injection. I thought I’d go into the whys and the wherefores of that in a little bit more detail.

The most important thing to realise with SQL Injection (and with all other forms of command injection) is that it requires that a user-inputted string be incorperated as part of a command that’s going to be executed. Not as part of a paramter value, but as part of the command itself.

Now, what about these two examples? Let’s assume that someone’s trying a SQL injection attack and has passed, for @inputParam, a value of “Table1; Drop Table Table1 –”

In example 1, that value that’s passed in does not match any of the IF conditions. Hence, the resulting SQL that will get executed is ‘SELECT * FROM ‘. That’s going to throw a syntax error, but nothing more. The malicious statement did not get injected into the command that was run. Hence, no SQL injection here.

What about example 2? For the same value of @inputParam, the command that will be executed is ‘SELECT * FROM Table1; Drop Table Table1 –‘. When that’s run, assuming sufficient permissions, Table1 is going to be dropped. Not good.

In this case, because the input parameter was made a direct part of the string that was getting executed, there was a possibility of SQL injection; this example is vulnerable.

Now let’s look at a couple of examples similar to the one I gave in my previous post, ones with dynamic where clauses.

In the first example, the imput parameters never become a direct part of the string that is being executed. They are used to control what portions are added to the string and they are passed, as parameters, to sp_executesql, but they themselves are not incorperated into the string.

In the second example, the parameters are used to control what portions are added to the string but they are also directly concatenated into the string. So whatever’s inside the parameters will become part of the string that is going to be executed.

So, what happens in this case if a malicious user passes, for inputParam1, this: “abc’; drop table SomeTable;–” and leaves inputParameter2 blank

In the first example, since inputParam1 has a value and inputParam2 does not, the resulting SQL string is

That is then executed by sp_executesql and the value with the attempted SQL injection is then passed as a parameter and the query executes looking for rows where Column1 has the actual value “abc’; drop table SomeTable;–” (which is quite unlikely to match anything). Since the input parameters did not become part of the string executed, there is no possibility for SQL injection here

What about the second example?

Well, in that example, if inputParam1 has the same value given in above and inputparam2 is blank, the resulting string that will be executed is

So, in summary, if a user-specified value is included as actual part of a SQL statement to be executed, it is vulnerable to SQL injection. If the parameters are used rather to control what the string looks like but are not made a direct part of it, then there is no opening for SQL injection. I hope this has cleared up at least a little bit of the confusion around the topic.