views:

121

answers:

4

A coworker and I were browsing SO when we came across a question about SQL Injection, and it got us wondering: how do parametrized queries work internally? Does the API you are using (assuming it supports parametrized queries) perform concatenation, combining the query with the parameters? Or do the parameters make it to the SQL engine separately from the query, and no concatenation is performed at all?

Google hasn't been very helpful, but maybe we haven't searched for the right thing.

+5  A: 

The parameters make it to the SQL engine separately from the query. Execution plan calculated or reused for the parametrized query, and then query is executed by sql engine with parameters.

Alex Reitbort
+1  A: 

Paramters make it to the SQL server intact, and individually "packaged" with meta data indicating their type, whether Input or Output etc. As Alex Reitbort points out, it is so because the parametrized statements are a server level concept, not merely a convenient way of invoking commands from various connection layers.

mjv
A: 

Parameters are passed along with the query (not within the query), and are automatically escaped by the API as they are sent in accordance with the underlying database communications protocol.

For example, you might have

Query: <<<<select * from users where username = :username>>>>
Param: <<<<:username text<<<<' or '1' = '1>>>>>>>>

That's not the exact encoding any database protocol actually uses, but you get the idea.

Justice
+1  A: 

I doubt that SQL SERVER builds a complete query string from the given parametrized query where the parameter list is concatenated in.

It most likely parses the given parametrized command string splitting it into an internal data structure based on reserved words and symbols (SELECT, FROM, ",", "+", etc). Within that data structure, there are properties/places for values like table names, literals, etc. It is here that it copies (verbatim) the each passed in parameter (from the list) into the proper section of that structure.

so your @UserName value of: 'x';delete from users --

in not never needs to be escaped, just used as the literal value it really is.

KM