PHP: Sanitize Data to Prevent SQL Injection Attacks
Posted on January 9, 2009, Filled under PHP,
Bookmark it
This is a simple function that sanitizes the data before sending it to MySQL. First it removes whitespaces from the beginning and ending of the string. If magic_quotes_gpc is enabled and the data has been already escaped we will apply stripslashes() to the data. This way the data won’t be escaped twice when mysql_real_escape_string() is called.
function sanitize($data)
{
// remove whitespaces (not a must though)
$data = trim($data);
// apply stripslashes if magic_quotes_gpc is enabled
if(get_magic_quotes_gpc())
{
$data = stripslashes($data);
}
// a mySQL connection is required before using this function
$data = mysql_real_escape_string($data);
return $data;
}The function mysql_real_escape_string() escapes special characters in a string for use in a SQL Statement. Unlike the deprecated function mysql_escape_string(), which doesn’t take a connection argument and does not respect the current charset setting, mysql_real_escape_string() calls MySQL library’s function mysql_real_escape_string, which prepends backslashes() to the following characters: \x00, \n, \r, \, ‘, ” and \x1a. It’s strongly recommended to use this function before sending any query to the mySQL database.
Example of unsecured script:
session_start();
$username = $_POST['username'];
$password = $_POST['password'];
$sql_query = "SELECT * FROM `members` WHERE username='".$username."'
AND password='".$password."'";
$sql = mysql_query($sql_query);
if(mysql_num_rows($sql))
{
// login OK
$_SESSION['username'] = $username;
}
else
{
$login_error = true;
}
The data sent is not sanitized. Therefore, the user could type anything he wants in the login form. Example:
$_POST['username'] = 'john'; $_POST['password'] = "' OR ''='";
The query sent to the database would be:
SELECT * FROM `members` WHERE username='john' and password='' OR ''=''
This way anyone could login without typing a valid password. The query selects all rows from `members` and the verification with mysql_num_rows() won’t work in this case.
Example of secured script:
session_start();
$username = sanitize($_POST['username']);
$password = sanitize($_POST['password']);
$query = sprintf("SELECT * FROM `members` WHERE username='%s' AND password='%s'",
$username, $password);
$sql = mysql_query($query);
if(mysql_num_rows($sql))
{
// login OK
$_SESSION['username'] = $username;
}
else
{
$login_error = true;
}
The %s from the sprintf() function indicates that the argument is treated as and presented as a string.
If an attack is made such as the one from the previous example the query sent will be:
SELECT * FROM `members` WHERE username='john' AND password='\' OR \'\'=\''
and will return an empty result set.
Happy coding!
Do you wish to receive the latest updates as soon as they are posted? Get our RSS Feed or Subscribe to the Newsletter!
- January 9, 2009
- article by Gabriel C.
- 11 comments
Related Posts
Construct SQL Query Statements in an efficient wayat December 29, 2008 with 4 comments
Create a PHP Script that Logins in to a Password Protected Areaat December 17, 2008 with 14 comments
Validate (input) usernameat August 29, 2008 with 2 comments
An AJAX (jQuery) Username Availability Checker with PHP Back-endat December 5, 2008 with 40 comments
Validate (input) passwordat August 30, 2008 with 2 comments

11 Replies to "PHP: Sanitize Data to Prevent SQL Injection Attacks"
January 27, 2009 at 7:53 PM
nice tutorial
July 18, 2009 at 2:41 AM
I’m going to have to use this. Thanks! But I have to be a smartass and point out the fact that that when sanitized, the code would let
johnlogin if his password actually was' OR ''='.July 18, 2009 at 10:22 AM
@Brian Recchia, are you sure? I’ve just checked this and there are no results returned for the query
SELECT * FROM `members` WHERE username='john' AND password='\' OR \'\'=\''April 6, 2010 at 7:33 AM
Don’t you have any protection on your registration? Are those values not being escaped before being entered into the database?
October 17, 2009 at 4:19 AM
Was on the hunt for a quick copy and paste sanatize function.
Whilst I like yours, there is one major issue. It is no reusable.
What if the user was to use PDO? Or a database other than MySQL?
Just a heads up
November 21, 2009 at 8:44 AM
Its a good thing you have this. Before I used to have that unsecured coding also and that bothered me a lot when I remember those sites that I have created in the past!
January 18, 2010 at 2:45 AM
This is my sanitize function in an application where I only expect user input without quotes, double dashes etc. What do you think of it?
sanitize( &$_GET );
sanitize( &$_POST );
function sanitize( &$some) {
foreach( $some as $key => $value ) {
$value = str_replace( '--', '', $value );
$value = str_replace( '/*', '', $value );
$value = str_replace( '"', '', $value );
$value = str_replace( "'", '', $value );
$value = ereg_replace( '[\( ]+0x', '', $value );
if ($value != $some[$key]) {
$some[$key] = $value;
}
}
}
May 26, 2010 at 2:01 AM
This is actually the wrong approach as the only definitively safe method is to use prepared queries. They take a bit more hassle, but really there’s no excuse for doing otherwise.
May 26, 2010 at 8:17 AM
Yes, they are recommended to use and indeed they take a bit more hassle, but I disagree that my approach is wrong. It depends which option is more convenient to the programmer.
June 7, 2010 at 4:27 AM
the arguement for the verification of the username should be a case insensitive string comparison.
August 6, 2010 at 3:48 PM
Hello, I use md5 for my user name/passwords logon
eg:
$my_user = md5($_POST['txt_user']);
$my_pass = md5($_POST['txt_pass']);
$valid_login_q = "select * from users where md5(user_name) = '$my_user' and md5(user_passw) = '$my_pass'
The users table is already indexed by a function based index for md5(user_name), do guys think that’s a good idea? I have been used before discovering other methods of “sanitization”.
See ya..