Search code examples
sqlsecuritysql-injection

SQL Injection in a Disguise


Sometimes SQL Inject queries may come in a disguise by using a different character set that you are used to. But even in those disguise modes, the query string would still include familiar words such as union and cast and varchar etc..

My question is this;

Is it possible to even disguise those words too? In other words, could "union" or "cast" be disguised as well?


Solution

  • The SQL standard requires that keywords use Latin characters A through Z or a through z, digits 0 through 9, and specific special characters. See SQL Language Elements in "SQL-99 Complete, Really".

    That said, individual implementations (e.g. Oracle, Microsoft SQL Server, MySQL) may not conform to the standard perfectly. The best way to be sure is to test the brand and version of RDBMS you use.


    Re your comments: MySQL allows /* */ comments to be embedded within keywords, but in other brands of databases, an inline comment is more or less like whitespace.
    So SEL/* */ECT is like SEL ECT which of course is not a valid keyword so it would fail.

    I assume that comment delimiters must also be characters in the ascii range, but I have not tested this to be sure. And it could vary by brand of RDBMS depending on implementation. So the answer must take that into account (hint: you haven't told us what brand of database you're using).

    Another type of "disguise" could be URL encoding. That is, using HTML entities or HTML hex-encoding for individual characters. SQL won't recognize these, but if you filter raw inputs before decoding, something could slip past your checks.

    Ultimately, my policy for the best practice is:

    • Never let user input be run as code (this also applies to any untrusted content read from a file or even from the database itself). Use parameterization or at least a dependable escaping function instead of interpolating content directly into SQL strings.

    • Parameterization doesn't help if you want to make other parts of your SQL dynamic based on user input. For instance, letting the user choose how to sort their result:

        SELECT * FROM MyTable ORDER BY $ColumnOfUsersChoice $AscVsDesc
      

    In that case my practice is to use whitelisting, so we compare the user input against a fixed set of valid choices, instead of trying to use pattern-matching with regular expressions. The advantage of whitelisting is that if a malicious user tries anything clever, their input will simply be ignored.

    For examples of whitelisting, see my presentation SQL Injection Myths and Fallacies or my book SQL Antipatterns Volume 1: Avoiding the Pitfalls of Database Programming.

    Here's a video recording of me presenting the SQL Injection Myths and Fallacies talk: http://marakana.com/forums/web_dev/general/210.html But I continue to improve the slides since that video was made, so there will be some differences.