Page 1 of 1

php security question

Posted: Sun Mar 02, 2003 4:47 am
by lazy_yogi
I had a job application for a php programmer and one of the questions was as follows :
Why is this section of PHP script insecure? How would you "fix" it?

<?
mysql_query("SELECT headline, body FROM article WHERE articleid=$_POST[articleid]");
?>
I assumed that it should check against valid articleid's, but just wondering what exactly the problem was and how to actually fix it

Posted: Sun Mar 02, 2003 5:04 am
by evilcoder
maybe because the user can alter it in the location bar???

.php?articleid=2

meh?!

Posted: Sun Mar 02, 2003 5:19 am
by lazy_yogi
no thats not it ... it's $_POST not $_GET
But you can easily modifiy it anyway by writing a simple script with the action going to that page with field articleid set as they want

cheers anyway



Anyone else know for sure what the security prob is ?

Posted: Sun Mar 02, 2003 6:06 am
by twigletmac
The $_POST variable hasn't been validated before you plug it straight into the query - you have no idea what the user is trying to use in the query.

Mac

Posted: Sun Mar 02, 2003 7:33 am
by volka
only e.g. (not a hacker tutorial so I chose something quite harmless)
make $_POST[articleid] 0 OR 1=1 and the query contains

Code: Select all

SELECT headline, body FROM article WHERE articleid=0 OR 1=1
that's true for all records.
Since the value is not quoted one can assume articleid is a numerical field. If there are no other constraints (e.g. user privileges) I'd implicitly cast the id like

Code: Select all

mysql_query('SELECT headline, body FROM article WHERE articleid='.(int)$_POST['articleid']);

Posted: Sun Mar 02, 2003 10:04 am
by CONFIQ
If magic_quotes_gpc is off then it's dangerous

Hacked can localy modify:
<input type=hidden name=articleid value"1';new mysql_query HERE" />

Posted: Sun Mar 02, 2003 12:42 pm
by Stoker
I would do something like this, assuming the var will never be zero (asuming magic_quotes_gpc is on

Code: Select all

<?php
  if (!$clean_int = (int) stripslashes($_POST['intvar'])) { /* do some error message */ }
  mysql_query('SELECT col1,col2 FROM tabl WHERE tabl_id ='''.$clean_int.'''');

  # or if it is a string and it may be fairly complex

  mysql_query('SELECT col1,col2 FROM tabl WHERE colstr ='''.mysql_escape_string(stripslashes($_POST['strvar'])).'''');
?>

Posted: Sun Mar 02, 2003 4:53 pm
by volka
hm. even with magic_quotes_gpc off and <input type=hidden name=articleid value"1';new mysql_query HERE" /> (int)$_POST['articleid'] will be 1, or did I forget something?

Posted: Sun Mar 02, 2003 5:09 pm
by Stoker
yeah if the submitted value is 1, but if the submitted value is 'beer' the result can be different probably 0, e.g. many SQL engines don't allow use of quotes when testing or setting data, so the var use results in 0 or a nullstring when something odd is inputed you may want to filter that before giving it to a query.