2

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.

doubleOrt
  • 2,407
  • 1
  • 14
  • 34
  • 3
    You *should* be safe, but why change methodologies if prepared statements are assured to work? – Jay Blanchard Jul 10 '17 at 17:47
  • That is exactly why i am asking this question, i currently DON'T USE prepared statements for the above and i wanted to use them, but since it seemed that i should be safe, as you described, i wanted to ask first instead of wasting my energy on redundant security. – doubleOrt Jul 10 '17 at 17:48
  • @Martin and is this guaranteed to work as efficiently as `filter_var()` ? – doubleOrt Jul 10 '17 at 18:09
  • 2
    Prepared statements are never redundant security. – ceejayoz Jul 10 '17 at 18:29

3 Answers3

3

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.

Jacobm001
  • 4,431
  • 4
  • 30
  • 51
  • As far as i know, i do have this filter all over my code and i am the sole developer. – doubleOrt Jul 10 '17 at 17:49
  • Are you talking about PDO in #3 ? – doubleOrt Jul 10 '17 at 17:53
  • @Taurus: you don't need to use PDO per say, though I'd recommend it. Bind parameters can be done in either mysqli or PDO. Maybe some other library, but I'm not particularly familiar with other alternatives, or why you'd want to use them over the two listed. – Jacobm001 Jul 10 '17 at 17:54
  • I do use PDO a lot in my code, but it is just that this code is from like half a year ago and converting every normal query to PDO is such a boring job, especially since PDOs can be quite long. – doubleOrt Jul 10 '17 at 17:55
  • 4
    @Taurus: In my opinion, it's worth it. Especially for code other people can see. – Jacobm001 Jul 10 '17 at 17:56
  • 2
    PDO's can be quite long? [You should read this.](http://jayblanchard.net/demystifying_php_pdo.html) @Taurus And if safe is equal to boring, then I am all for being bored. – Jay Blanchard Jul 10 '17 at 18:44
  • 1
    @JayBlanchard cool function :) looking forward towards using it in my app. – doubleOrt Jul 11 '17 at 07:12
2

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.

Martin
  • 22,212
  • 11
  • 70
  • 132
1

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

Ebrahim Poursadeqi
  • 1,776
  • 2
  • 17
  • 27