I understand that the safest way to protect your website from SQL injection is to use Prepared Statements. But how does someone can go around this if user input is converted to a number?
$id = (int)$_GET['id'];
I understand that the safest way to protect your website from SQL injection is to use Prepared Statements. But how does someone can go around this if user input is converted to a number?
$id = (int)$_GET['id'];
But how does someone can go around this if user input is converted to a number?
Simply put, they can't, end of story/hits brick wall. Since it's been casted as an integer, it cannot be modified or manipulated from thereon.
Only you have that power to modify it, if you wanted/had to.
For example:
$string = "String";
$id = (int)$_GET['id'];
echo $new_value = $string . "" . $id;
Producing String123.
A var_dump($new_value); will produce string(9) "String123".
But now, that would be a string, so you didn't want that, but it's just to show you what can be done, after the fact.
Since an SQL injection usually contains characters such as ', - or DELETE or anything else that isn't an integer and passed into by a potential hacker, the statement will be rejected.
file.php?id=123 and modified in the URL such as file.php?id=String'); DROP TABLE USERS; -- will not "pass GO", as it were.
What you could do is to check if what is being passed in the array is indeed an integer.
There are a few functions to check for this.
filter_input() with the FILTER_VALIDATE_INT filterHowever, using a prepared statement would also be beneficial. Both the mysqli_ and PDO apis offer this.
When using for instance the mysqli_ api and then using something such as:
bind_param("i", $id) (the i for "integer"). Even if someone did manage to pass something other than an integer, mysql will still refuse to let it go through, since it was also casted as an integer through the binded argument.
Yet, if that were bind_param("s", $id) - (the "s" for "string"), then that could be a different ballgame.
PDO has this also, being PDO::PARAM_INT.
With that said; stick to using a prepared statement, regardless.
IN() mysqltutorial.org/sql-in.aspx where and if the id value is indeed an integer and the column type would fail, since it cannot be quoted.