Thursday, October 14, 2010

How to check for basic SQL injection vulnerability in a web application...

With all the new applications being built on the web platform and their overt dependence on database systems, there are a few security accessories that need to be attached to these Web Applications to secure them from hackers and other persons with malicious intent.

Here, I'm telling you a simple test to check your web applications against the most common vulnerability (Almost 60% are vulnerable) associated with web applications using database systems, and that is SQL INJECTION VULNERABILITY.

As the name suggests(or does not suggest), a hacker performs an attack by injecting SQL statements into inputs considered as the legitimate inputs. These inputs if left unfiltered and are sent to the DBMS, a hacker can do anything with your data.

A simple test is given here...,

Step 1> Open the web application you want to test, suppose a login page appears..

Step 2> Now type this in the username

' or 1=1 --
OR
' or 1=1 #

and type anything in password field and click login/signin etc.

Now, if you see a screen telling you that you are authenticated or authorised, then this application/site is vulnerable to SQL injection. If not try putting the same string in password field also.


How does it work??

To authenticate a user the username and password are fed into the DBMS like this

SELECT username, passwd FROM TBLOGIN WHERE username = '$username' AND passwd = '$passwd'

and if it returns a record, user is authenticated.

where $username and $passwd are the unfiltered inputs by the user. This works fine as long as legitimate users are using the app. But once u enter these strings, upon replacing variables in the SQL Statement with input data, the statement becomes somewhat like this

SELECT username, passwd FROM TBLOGIN WHERE username =' ' or 1=1 --' AND passwd = 'random_keys'

Now, DBMS interprets the statement until -- in case of MS SQL server and until # in case of MySQL server as these are the single line comment identifiers, that is the DBMS takes the rest of the line meaningless as a comment.





The actual interpreted statement becomes
SELECT username, passwd FROM TBLOGIN WHERE username =' ' or 1=1
Which always returns a record as 1 is always equal to 1.

Note: This is the simplest of all the tests on SQL injection. If your app passes this test, it doesn't guarantee safety of your application. Now that you have understood it, you can experiment with your own applications with various other combinations of strings or numbers.

Now, the Cure section
As an Ethical Hacker it is my responsibility to spread awareness about vulnerabilities, so here's how to minimize the risk of SQL Injection:

1. At the application level:
a) Always filter out the special characters from the user given input before any other processing until and unless specifically required.
b) Put maximum and minimum character limits on the input strings.
c) Never pass the input variables directly as arguments, use parameter/other objects built in the languages that check n verify data type/ validity etc.

2. At the database level:
a) Grant only those privileges to a user that it is intended to perform such as a user who needs to read the data must be granted select privileges only just in case he is compromised he can do little damage.
b) Create separate users for different operations like delete, drop, update, select etc.
c) Create table, database and column names that are not very common and can't be guessed easily.

These are some basic steps to secure your applications. There are now some DBMS which offer built-in attack detection.

No comments:

Post a Comment