How can I trick the script into thinking this SQL is valid?
You can’t trick it into thinking it is valid SQL. You actually have to make it valid SQL.
It may help when you echo the resulting SQL statement to see the actual result:
$stmt = "SELECT * FROM users WHERE username ='" . $user . "'";
echo $stmt;
if ($result = $db->query($stmt)) {
// …
}
Since the injection happens in a MySQL string literal, you have to provide SQL fragments that allow you to escape from that string literal. Since the string literal is enclosed within single quotes, a single single quote would denote the end delimiter and any following data is no longer interpreted as string:
user: whatever' OR '1'='1
This would result in:
SELECT * FROM users WHERE username ='whatever' OR '1'='1'
# \_________________/
# injected
Note that mysqli::query
does only execute one single statement. That’s why the second statement causes an error. So the second DROP TABLE
statement example doesn’t work here.