1

I have some links structured as follows...

http://domain.com?problem_id=23&course_id=4

The expected values from the GET "fields" (problem_id and course_id) are to be integers. Can I validate this data by simply saying...

if (is_numeric($_GET['problem_id'])){
   //It's safe, so do stuff.
} else {
   echo 'It appears you submitted a problem incorrectly.  Please contact us for assistance';
   exit;
}

Or is this still open to nastiness like sql injection, etc.?

PROPOSED SOLUTION

$int_problem_id = (int) $_GET['problem_id'];
if (ctype_digit($int_problem_id)){
   //It's safe, so do stuff.
} else {
   echo 'It appears you submitted a problem incorrectly.  Please contact us for assistance';
   exit;
}
gtilflm
  • 1,389
  • 1
  • 21
  • 51
  • http://stackoverflow.com/questions/60174/how-to-prevent-sql-injection-in-php – ozahorulia Jun 22 '13 at 17:00
  • 2
    Note that [`is_numeric()`](http://php.net/manual/en/function.is-numeric.php) may not be actually doing what you think it is. The following will all return true for is_numeric: `3.14`, `+0123.45e6`, `0xf4c3b00c`, `0b10100111001`. Is [`ctype_digit()`](http://www.php.net/manual/en/function.ctype-digit.php) what you're looking for instead? – jcsanyi Jun 22 '13 at 17:21
  • @jcsanyi: Using ctype_digit is a better way. Thanks! – gtilflm Jun 22 '13 at 17:28

2 Answers2

2

Yes, it is a solution. Also, you can additionally cast to int.

$integer = (int) $_GET['problem_id'] ;

You should secure all the input for your database even though numeric values will do no harm as they do not contain special symbols.

sybear
  • 7,837
  • 1
  • 22
  • 38
1

You would have ensured that ?problem_id= is numeric. All of your other fields may still be at risk though, so this isn't the proper way of securing against SQL injection. You should look into PDO and MySQLi, and their bindParam/bind_params functions.

SpenserJ
  • 802
  • 5
  • 13
  • Right. Also, sorry, but this data is actually coming in via a URL. Please see my revised post. Is your answer still valid? – gtilflm Jun 22 '13 at 17:21
  • Yes it is. ?problem_id means it is a GET parameter, accessible through $_GET['problem_id'], so you're on the right track. What you do with the variable is what matters, and you can either write a straight mysql query (at which point you're vulnerable to SQL injection) or use PDO/MySQLi to write the query for you. Both of them will safely escape the variable, regardless of type. With an integer, it will bind it as an integer, however someone submitting `?problem_id=1; DROP TABLES` will have their query escaped, and it won't do any damage. – SpenserJ Jun 22 '13 at 17:25
  • Right. I actually won't be interacting with the database. So, I think I should be pretty safe using my proposed solution above. Thanks for replying. – gtilflm Jun 22 '13 at 17:38