Preventing SQL Injection in PHP - Select
PHP code is vulnerable to an SQL injection attack when it takes user input and directly adds it to an SQL query string.
example:
<?php // Query database to check if there are any matching users $query = "SELECT * FROM users WHERE user='".$_POST['username']."' AND password='".$_POST['password']."'"; mysql_query($query); // We didn't check $_POST['password'], it could be anything the user wanted! // For example: $_POST['username'] = 'zedwood'; $_POST['password'] = "' OR 1=1"; echo $query; ?>
In the above example, the user is able to inject some sql into the password field... and the program blindly passes it into sql. The generated query string is
SELECT * FROM users WHERE user='zedwood' AND password='' OR 1=1
This query allows them to login without a password. So... this is bad. Now, how to protect against it...
From php.net the following is recommended:
<?php $query = sprintf("SELECT * FROM users WHERE user=%s AND password=%s", mysql_real_escape_string($_POST['username']), mysql_real_escape_string($_POST['password']), ); ?>
but....
thats a lot of code to have to enter for every time. Instead use this function, qsprintf:
<?php //way less code $query = qsprintf("SELECT * FROM users WHERE user=%s AND password=%s", $_POST['username'], $_POST['password'], ); //here is the code function qsprintf() { $numargs = func_num_args(); $arg_list = func_get_args(); $format = $arg_list[0]; $next_arg_list = array(); for ($i = 1; $i < $numargs; $i++) $next_arg_list[] = mysql_real_escape_string($arg_list[$i]); return vsprintf($format, $next_arg_list); } ?>
Note 1:
due to % symbol, qsprintf doesn't work very well with this SQL query: select * from users where first_name like '%scott' because it will interpret %s of scott as the %s format specifier used in printf.
Note 2:
it is a good idea to replace the call to mysql_real_escape_string above, with a custom quote function in order to take care of magic_quotes.
<?php function quote($value) { if (get_magic_quotes_gpc()) $value = stripslashes($value); if (is_numeric($value)) return "'$value'"; return "'".mysql_real_escape_string($value)."'"; } ?>
code snippets are licensed under Creative Commons CC-By-SA 3.0 (unless otherwise specified)
![]() |