doubleOrt
doubleOrt

Reputation: 2507

Am i safe from SQL injection if i know for sure that a certain value i am using in a dynamic statement is an integer?

Before i make my query, i check if the variable that is to be used in that query is an integer using this code: filter_var($_POST["user_id"], FILTER_VALIDATE_INT) !== false.

My question is, should i use PDO or do any escaping if the above function returns true only if my value is an integer (meaning that the value i am to use to build my query is safe) ? Is there any need to escape the value using prepared statements if my value has already passed the above test ?

I have not done any testing with the above nor am i really experienced in server-side technologies, so it is up to you PHP/security experts to guide me.

Upvotes: 2

Views: 126

Answers (3)

Martin
Martin

Reputation: 22760

This answer is an explanation of the shorthand type casting, from comments, as it's easier to read it as an answer than as a set of comments.

Your code:

filter_var($_POST["user_id"], FILTER_VALIDATE_INT) !== false. 

This is a long winded way of ensuring that POSTed data is integer. It has issues, because POST data is always cast as a string.

 $_POST["user_id"] = (int)$_POST["user_id"]; 

Is much easier to read and shorter to type, and this forces the data to be the integer type. This will competely solve your security risk if putting non-integer data into an integer placement in your SQL.

This utalises PHP Type Juggling which it is well worth reading up on.

While the above code will solve your security aspect, it will raise other overlap issues because any string can be casted to an integer, but the cast will return 0 if the string doesn't start with an integer value.

Example:

$string = "hello";
print (int)$string; // outputs 0;

$string = "27hello";
print (int)$string; // outputs 27;

$string = true;
print (int)$string; // outputs 1;

$string = "";
print (int)$string; // outputs 0;

So, overall I would suggest the following line to ensure your given POST value is a correct integer:

if (strcmp((int)$_POST['value'], $_POST['value']) == 0){
    /// it's ok!
}

Please see this answer for further details as well as this PHP manual page.

Upvotes: 2

Ebrahim Poursadeqi
Ebrahim Poursadeqi

Reputation: 1816

maybe you need to see php bugs page this page before use FILTER_VALIDATE_INT

Upvotes: 1

Jacobm001
Jacobm001

Reputation: 4539

It's still a good idea to use prepared statements. Bind functions at this point are tried and true.

  1. What if you or someone else screws up the filter?

  2. Are you going to remember to use the right filter at every point in your code? This is a very easy thing to mismanage, and sometimes you may not be able to plan for every eventuality. Integers are relatively easy, but strings are far more complex.

  3. In regards to your professional reputation, will other people see this code? If you had open source code (like github or something), and I was a hiring manager looking into your history, I would not hire you for breaking such a standard security practice like this.

Admittedly, point 3 is a little off topic, but I feel that it's worth mentioning.

Upvotes: 3

Related Questions