What is SQL Injection?
Many sites use databases as a back-end to store their data, using queries to insert and select data from it. However, many people are unaware that such sites are often vulnerable to a form of attack called SQL injection.
SQL injection is when malformed user input is used directly and deliberately in an SQL query, in a way that allows the attacker to manipulate the query. This means that an attacker could delete portions of your database, make himself an admin account etc, the possibilities are endless.
One of the most common vulnerabilities is when logging in to a site. Take this example:
$username = $_POST['username'];
$password = $_POST['password'];
$result = mysql_query("
SELECT *
FROM
site_users
WHERE
username = '$username'
AND
password = '$password'
");
if ( mysql_num_rows($result) > 0 )
// logged in
This is vulnerably to a pretty obvious SQL injection; can you work out how an attacker could modify the query to allow himself to be logged in regardless of whether or not he has the right password?
If the attacker enters a valid username in the username field: "rob" and the following in the password field: ' OR 1=1 '
The resulting query will look like this:
SELECT *
FROM
site_users
WHERE
username = 'rob'
AND
password = '' OR 1=1
It will therefore select all users where:
• the username is "rob"
• either the "password" field is empty, or 1 is equal to 1
Since the last criteria will always be true—when is 1 ever not equal to 1?—, the user will be able to log in as rob without knowing rob's password !!
How can we prevent SQL injection attacks?
As with XSS attacks, you must never trust user input. The best way of cleaning user input is using PHP's built in mysql_real_escape_string() function; this will escape characters such as ', " and others, making them useless in "breaking out" of a quoted string as in the above example. If you're using a number in your query, then you should use intval() on the inputted number to ensure it is numeric.
I have also made the following function that can be used to discard any characters that can be used to manipulate the SQL queries. So, you can use this functions just as well to validate your SQL queries:
function is_valid($input)
{
$input = strtolower($input);
if (str_word_count($input) > 1)
{
$loop = true;
$input = explode(" ",$input);
}
$bad_strings = array("'","--","select","union","insert","update","like","delete","1=1","or");
if ($loop == true)
{
foreach($input as $value)
{
if (in_array($value,$bad_strings))
{
return false;
}
else
{
return true;
}
}
}
else
{
if (in_array($input,$bad_strings))
{
return false;
}
else
{
return true;
}
}
}
Function Usage
This is how you can use the above function:
if (is_valid($_REQUEST["username"]) == true && is_valid($_REQUEST["pass"]) == true)
{
//login now
}
However, don’t depend on this function alone, you must still use the mysql_real_escape_string() function in your SQL query. You can also modify this function or you can get a new idea to work out of this function.
