Vendor A says his tool discovers SQL Injection. Is that true?
He is partly true. Most tools today can discover the simple form of SQL Injection. Unfortunately, most of them miss out every other form.
Let’s see what is going on.
In a SQL Injection attack, the adversary induces the database to run SQL commands that he provides. The simplest way to discover if an input is vulnerable to SQL Injection is to manipulate the input, and see the response. [There are over 30 manipulations, we’ll come back to that in a jiffy.] If the server throws back a database error message, usually an ODBC error message, the adversary knows that the input he gave went all the way to the database – that’s why the error message came back from the database.
So here’s how we discover the simplest form of SQL Injection: if the response includes a database error message, then the app is vulnerable to SQL Injection. Every scanning tool we have seen uses this logic. Some extend it to other error messages too.
But an app can be vulnerable to SQL Injection and not throw any error messages to the user. When the input reaches the database, it gives an error to the application. But the application, as part of common courtesy, usually hides the error message from the user. Thus, an application can be vulnerable to SQL Injection and yet hide all error messages from the user. In such cases, a scanner wrongly concludes that the app is safe.
The right way to find SQL Injection in such cases, (and this is by far the most common case today), is to infer from the app’s behavior that it ran the manipulated input we gave it. Most pen testers have learnt how to make these deductions and refine the exploit step-by-step to expose the vulnerability.
A variation of the simple SQL Injection attack (called Blind SQL Injection) is designed to test for SQL Injection attacks without looking for the error message. Some tools, notably Spidynamics WebInspect, use Blind SQL Injection also in their repertoire.
Now, more about those 30+ manipulations to test for SQL Injection. They are sometimes called test cases, sometimes Injection strings, at times fault injectors. They are refinements over the basic SQL Injection test case which is a simple single quote: ‘ That single quote has the power to throw an error message. Most of the 30-odd refinements improve our ability to exploit SQL Injection. If you just want to know whether the app is vulnerable, the single quote suffices. Many scanners and testers boast how many different “test cases” they use for SQL Injection. The number is really unimportant. Whether you use 15 or 30 or 50 test cases, discovering SQL Injection is about making the right inferences from a few simple inputs. All the other test cases are only for exploitation, after you are able to discover a vulnerable variable. Thus, all these boasts about the number of test cases is misplaced. It doesn’t matter if you have a 100 exploit refinements if you can’t spot the right variable that’s vulnerable to it.
Our favorite piece on SQL Injection is the Advanced SQL Injection paper by Chris Anley. It explains the sequence of inferences a tester has to make to refine his test cases.