
Originally Posted by
felgall
"But I don't see how real_escape_string when used properly is less secure."
The text in bold is what makes the difference between the two. With prepare/bind you don't need to look at anything other than the prepare and bind calls to know whether it is 100% secure or not. With real_escape_string you need to look at the query and then track back all of the data references to where they were validated in order to see whether they might contain something that needs to be escaped and then examine the intervening code to confirm that those fields that need to be escaped are escaped.
Oh, now I see where our assumptions are different. When real_escape_string is used like you described above, that is *only* when necessary at all costs, then yes, it can become harder to spot security holes. But by proper use I mean escaping values always, no matter whether they come from a sanitized source or not. In such case there's no difference because we are doing the same amount of work - you have to make sure that all your variables are bound, I have to make sure that all of my variables are escaped. Therefore, I don't need to track my code back to where the values come from, I just know that all of them must be escaped right where I inject them into my query.

Originally Posted by
DrQuincy
Aside: Could you elaborate on this? If a number is outside PHP's storage range, what happens?
Sorry, I wasn't clear enough, I was specifically commenting on this method:
PHP Code:
$number = (int)$_GET['myvalue'];
Imagine that myvalue is 18446744073709551610. This number is within mysql BIGINT UNSIGNED range but is too large for PHP to handle so after casting to INT this is what you will get on a 32-bit system:
2147483647
It will be larger on 64-bit systems but still the value will be changed because it is too large to be handled as a 64-bit signed integer, which PHP uses. Similar problems arise when you use $number = (float) $_GET['myvalue'];. Aside from the same problem of 'truncating' the number to another within the allowed range you take the risk of losing precision. Imagine you have this number:
1844674407370.123456789012
which mysql can store just fine in a DECIMAL field with perfect precision. PHP doesn't support precision decimal numbers so casting to a float is as good as you can get. But then the number will be changed to
1844674407370.1
Of course, PHP can handle such numbers just fine when you store them as strings so that is what you should do in such cases.
Also beware of filter_var - while the numbers won't be changed the filtering mechanisms are very dumb as they apply some very simple character removal. So a number like this will pass the filtering without problems:
PHP Code:
filter_var('---184467440++++7370123456789012---', FILTER_SANITIZE_NUMBER_INT);
Using such a number will result in SQL syntax error - you will prevent SQL injection in this way but having syntax errors is something you would probably also want to avoid. This is why I generally dislike the filter_ functions in PHP - while the idea is nice, the implementation is far from satisfactory...
When you sanitize your numbers with is_numeric() then you avoid such problems. Prepared statement should also work fine.

Originally Posted by
DrQuincy
I see your point and actually think we're all agreeing with each other. Lemon Juice and I are saying that real escape is 100% secure if used on string. Your point is that you can execute a query and not run escape for whatever reason (you forget, code patch, whatever) whereas with prepared statements you must bind the params before executing so injection cannot occur.
To be pedantic you could “forget” to escape a dynamic table name generated from user input when using prepared statements and still suffer an injection.

Yes, it basically comes to coding standards and for security reasons you always have to do something with the values, whether you are binding them or escaping. When you do that always then you are safe.
Moreover, I believe that prepared statements are not the right tool for avoiding sql injections. While they have this nice side effect I believe it is a kind of workaround when they are used only for that reason. I can see a few downsides of using prepared statements in this manner - but maybe I'm going too much off-topic here
.
Bookmarks