Saturday, March 13, 2010

SQL Injection

Do you test an application which uses a database? If you do you should be testing for SQL Injection.

What is SQL Injection? It is when the input to the application allows queries to be sent to the database which the programmer did not intend. To make it more clear, here is an example.

A web application has an administrator log in which checks the username and password against an entry in a database. The user inputs:

Username: admin'; --
Password: whatever

This seems odd but harmless. Now let's look at some potential code:

statement = "SELECT * FROM users WHERE username=' + userName + "' AND password='" + passWord + "';"

Given the input from the user, the SQL statement becomes
SELECT * FROM users WHERE username='admin'; -- 'AND password='whatever';
If the administrator's username is admin then this will return the rowset for the administrator. Here is how it works. The -- in MySQL is a comment. Everything from the -- to the end of line is a comment. So the above statement might as well be:
SELECT * FROM users WHERE username='admin';
It eliminates the check for the correct password. This is a known hack and I would be DEEPLY surprised if you find this simple mistake. The solution is simple. Check the user input before sending it to the method that builds the SQL statement. We could either reject input with semicolons, SQL comments, etc. or we could escape them. That is, change the input so things like ' become \'.

You might have noticed one thing. I mentioned that -- is a comment for the MySQL database. How did I know it was the MySQL database? Maybe I didn't and I'm just guessing. Actually, as a tester I would know which database it is but as a hacker, how would I know? It is actually quite simple. Peek under the covers.

Sometimes there is information in the HTTP headers that reveals information about the technology being used at the site. Also, have a look at how data is getting sent to the server. If it is a form with POST or GET parameters, I can fake those. Let's say the HTML source code for http://my.site.com/myapp/ is:

<form action="login.action">
    <input type="hidden" name="key" value="293674"/>
    Username: <input name="username" value=""/><br/>
    Password: <input type="password" name="password" value=""/>
</form>

I can go:

http://my.site.com/myapp/login.action?key=293674&username=admin&password=wildguess

Or I could change the value of the hidden inputs until I get an error from the application server. Usually the error messages will have something in them to tell me what technology is being used. Worst case, if the site administrator is smart enough to hide the database we can use syntax that works on all databases or just try hacks we know work for MySQL in hopes you are using that.

So if there are known security flaws in your database, you want to make sure you get them patched or the software guards against them.

So how do you test for this? You could become the ultimate hacker and discover new and innovative ways to inject data into SQL queries. Or you could use some common tools for generating SQL Injections. Here is a list of possible site to start with, in no particular order:

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.