WebApp Sec mailing list archives

Re: Security of magic_quotes_gpc under PHP against SQL injection


From: ascii <ascii () katamail com>
Date: Mon, 12 Dec 2005 22:04:16 +0100

Peter Conrad wrote:
... SELECT whatever FROM whereever WHERE id = $input ...
..
Like most of PHP's "security features" is was introduced as a workaround
for stupid developers who don't know or care about security.

i agree, only proper use of single quotes will save you
(eg. WHERE id = \''.$input.'\' ...) in this case

any type of input should be used inside single quotes, also
booleans and integers (if not casted or validated)

also there are some differences between addslashes (magic_quotes_gpc
apply addslashes on all GET, POST, and COOKIE arrays but not on SYSTEM
and ARGV) mysql_escape_tring and mysql_real_escape_string

imho addslashes (and magic_quotes_gpc) is bad cause of:

- not all inputs are validated by addslashes

- people that forgot to apply proper validation (and witch security
relay on php workarounds) easily forgot to stripslashes vars and protect
against (stupid and dangerous) xss (htmlspecialchars, htmlentities and
so on)

- when you write something relay on a specific server configuration
you app become less portable

- i use escaping by myself and on magic_quotes_gpc on servers i have to
check for get_magic_quotes_gpc()

// php example on http://it2.php.net/get_magic_quotes_gpc
if (!get_magic_quotes_gpc()) $lastname = addslashes($_POST['lastname']);
else $lastname = $_POST['lastname'];

// what i have to do in case of magic quotes
if (!get_magic_quotes_gpc())
 $lastname = mysql_real_escape_string($_POST['lastname']);
else
 $lastname = mysql_real_escape_string(stripslashes($_POST['lastname']));

// put this in a little function if you want
fucntion escape_post($key){
 if (!get_magic_quotes_gpc())
  return mysql_real_escape_string($_POST[$key]);
 else
  return mysql_real_escape_string(stripslashes($_POST[$key]));
}

- \n and \r are not escaped by addslashes

- there are a lot of encoding attacks (like base64 and uuencode)

- there are some charset tricks (this is why mysql_escape_tring !=
mysql_real_escape_string and you should use mysql_real_escape_string)

in c/c++ you have to do strict input validation why in php it should
be different? proper (and positive/whitelist) validation assure you
a safer flow of your code (i think casting, ctype and pcre are the best
and fastest options you have in php)

// cast the value (an int, no escaping required)
(int)intvalue($_GET['id']);

// validate the value (an int, no escaping required)
(preg_match('/[0-9]{6}/', $_GET['id']))?(int)intvalue($_GET['id']):NULL;

// validate the value (a string, escaping required)
(preg_match('/[a-zA-Z0-9(and some other harmful chars)]{69}/', $_GET['id']))?mysql_real_escape_string($_GET['id']):NULL;

the difference between pure casting and validation is that validation
permit logging (i love trigger_error and set_error_handler combinations
to log and mail errors, with also ob_start/ob_get_clean to give the user
a friendly message)

if magic_quotes_sybase is also on, a single-quote is escaped with a
single-quote instead of a backslash, so there are two 'race conditions'
(the usage of mysql on a magic_quotes_sybase on server and the usage of
sybase on magic_quotes_sybase off server)

i'm sorry for the long email

ascii - http://www.ush.it


Current thread: