2

This is the query:

$mysqli->query("UPDATE `users` SET `user_age` = '$my_age', `user_sex` = '$my_gender', `user_description` = '$my_description'
            , `user_sound` = $my_sound, `country` = '$my_country', `region` = '$my_region', `custom1` = '$mycust1', `custom2` = '$mycust2' WHERE `user_name` = '$me'");

What makes it vulnerable is the $my_sound variable which isn't wrapped in the apostrophe ('). I've looked up many times on google but couldn't find much intel related to why SQL injections are doable when a variable in a query isn't wrapped in (')s.

How would an attacker exploit this query?

  • 2
    Check out this stackoverflow thread - it contains the answers to your question! – game0ver Jul 14 at 19:24
  • 1
    $my_sound = "2, `is_admin` = 1" -- or if they want to DoS, "2, `pwd_hash` = "$2y$10000$so82Q5okFHd6sa8vRPC09OyGFlWzNMKir.c2lgXKsEaP/gG.I/2Y2", then try to log in repeatedly (Similar for Argon2: $argon2d$v=19$m=1048576,t=1048576,p=1$MTI1MnUxMml1M2l1Mml1MWl1M2kxdTRpMXU1aTF1MmkzdTFpdTFp$iGPeWxFFsuf3AITq7tUrZ5XlJ/o/jhiUz9CvBgvjiEU). You can either spend a ton of time and effort trying to figure out every possible attack vector... or just use correct, parameterized SQL, so that they'll end up setting their sound to an invalid value instead of breaking your server. – Nic Hartley Jul 14 at 20:38
  • 2
    I agree with the comments. Your query is vulnerable because you’re using variable substitution in an SQL query. Prepared statements are the proper protection – Andrew Morozko Jul 14 at 22:03
  • "How would an attacker exploit this query?" (blind) based time injection meaning using (SELECT SLEEP(5)) for example and time the response time if goes over 5 seconds.. This (blind) based time injection injection should work for UPDATE/INSERT/DELETE queries.. In a answer on stackoverflow (post off mine) explains it more in detail. – Raymond Nijland Aug 6 at 21:59
6

Generally, SQL Injections happens when an unsanitized variable is used within a query, regardless of whether there is an apostrophe or not.

In PHP you want to use prepared statements. This will transform your query into:

$sql = "UPDATE `users` SET 
        `user_age` = ?, 
        `user_sex` = ?, 
        `user_description` = ?, 
        `user_sound` = ?, 
        `country` = ?, 
        `region` = ?, 
        `custom1` = ?, 
        `custom2` = ? 
    WHERE `user_name` = ?";

// Prepare the statement
$statement = $mysqli->prepare($sql);

// Bind your variables to the question marks in the SQL.
// bind_param keeps variables bound, so if you prepare a statement, bind the params 
// then change the value of the variable bound, then the new value will be used.
// The first parameter determines what type of value, 's' is a string, 'i' is a interger
$statement->bind_param("sssisssss", $my_age, $my_gender, $my_description, $my_sound, $my_country, $my_region, $mycust1, $mycust2, $me);


$statement->execute();


Note that you don't need apostrophies when using prepared statements, the s type definition in bind_param will add them for you when escaping the value.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy