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 = md5(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!
- January 9, 2009
- article by Gabriel C.
- 18 comments
Related Posts
-
Create a PHP Script that Logins in to a Password Protected Areaat December 17, 2008 with 14 comments
-
How to Create a PHP AutoLogin (‘Remember Me’) Feature using Cookiesat November 25, 2008 with 29 comments
-
Validate (input) passwordat August 30, 2008 with 2 comments
-
Validate (input) usernameat August 29, 2008 with 2 comments
-
PHP: Practical cURL functionat September 2, 2008 with 2 comments

Comment via Facebook
18 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..
December 18, 2010 at 5:00 AM
$valid_login_q = “select * from users where md5(user_name) = ‘$my_user’ and md5(user_passw) = ‘$my_pass’
I think you really mean:
$valid_login_q = “select * from users where md5(user_name) = ‘$my_user’ and user_passw = ‘$my_pass’
Your password should already be stored in the database as md5 hashes, not plain text.
February 2, 2011 at 12:50 AM
Well… yes MySQL stores md5 password, but user inputs not md5 so code sgould convert it to md5 first to compare with database entry.
February 20, 2011 at 3:09 AM
Dont you think it should be addslashes() instead of stripslashes() ?
February 20, 2011 at 3:23 AM
No, because I already use
mysql_real_escape_string()which is used to escape special characters in a string for use in an SQL statement . The role ofstripslashes()here is to remove any existing slashes that may result ifget_magic_quotes_gpc()is enabled. This way, the string won’t be retrieved with multiple slashes in the end. Hope that makes sense!February 20, 2011 at 4:13 AM
Thanks for clearing the confusion. That makes a lot of sense!!
March 7, 2011 at 11:54 PM
Do NOT use this as protection in any real-life application, it is a very unsecure and wrong aproach.
It may work for strings, but if you have a numeric value escaping strings does not make any change.. example:
…&id=5 union select @@version, null, null
so you don’t need the tick to perform a sql injection, you can even do where statements using the concat and char function of mysql concat(char(34), char(32)…)…
So, i recommend to use a prebuilt library (framework or orm like propel) or use prepared statements, since they are not vulnerable to sql-injection.
August 15, 2012 at 9:35 PM
This adding and stripping slashes is confusing me.