• First off, I thought the QotD was great. I've read about this attack, but hadn't yet seen an example of how it was executed.

    scott (6/9/2008)


    Hmmm, interesting topic. Definitely something to be aware of. I see alot of "Dynamic SQL is evil" posts but one thing sticks out at me that is an old C/C++ trick I use (It's a good way to ensure that you don't mix up your "==" and "=").

    If, for example, the "account=1" is used as...

    "SELECT * FROM Accounts WHERE AccountNumber=" & Request.QueryString("account")

    Then changing this query to...

    "SELECT * FROM Accounts WHERE " & Request.QueryString("account") & "=AccountNumber"

    Returns an error.

    Just my 2c...

    This is just security through obscurity. There are several problems with this approach. First, many developers who are too lazy to properly parameterize the statement (which would be the correct way to fix this), are also likely to display the error message returned from SQL server somewhere on the page. For example, the error message I get from your solution is this: "An expression of non-boolean type specified in a context where a condition is expected, near ';'". So I can simply change my attack to this:

    1=1;{add my hex attack here};--

    The 1=1 will prevent the error, and then by ending the attack with the line comment I can remove the trailing command from the query definition.

    The way to properly prevent ANY and ALL injection attacks has already been stated:

    1) use Parameter objects along with a Command object

    2) If you MUST dynamically add other clauses to your statement, NEVER, NEVER, NEVER use the user's direct input as part of your concatenation.

    examples of #2:

    dynamic ORDER BY

    string cmd = "SELECT col1, col2 FROM myTable ORDER BY " + Request.QueryString["input"]

    dynamic procedure name

    string cmd = "myStoredProc" + Request.QueryString["input"]

    DbCommand query = new DbCommand(cmd);

    query.CommandType = CommandType.StoredProcedure

    .....

    In the case of #2 use an enumeration or a whitelist of some kind if you must write statements like those above.

    The sad thing here is that the answer to this for many will simply be to update their blacklists or some other hack instead of properly fixing the issue which has been so well documented. IMHO, I blame poorly written documentation, poor articles posted on the web and lazy (read: poorly written) forum responses which suggest (implicitly) to the reader that it is ok to write SQL which is wide open to these attacks. When writing any of the above the other should take the responsibility to write examples properly and assume that for every 1 person who knows to translate the example to a proper statement there will be 100 noobs who will copy and paste his example into their code and never give it a second thought.

    The repercussions of not properly writing ad hoc queries is serious. Getting the list of databases is tame by any measure. It would be so easy for the attacker to upload an XSS attack to a forum and place malware on all your visitor's machines. This should be such an easy thing to fix, but too many people think, "It won't happen to me".