EXERCISE 1 — Injecting into an UPDATE: escalation and mass modification ======================================================================= THE VULNERABLE STATEMENT: UPDATE users SET nickname = '$n' WHERE id = $id (both $n and $id built by concatenation of user input) (a) ESCALATE THE ATTACKER'S OWN PRIVILEGES: Inject an EXTRA column assignment via the nickname value. Set: nickname (input): x', role = 'admin Resulting query: UPDATE users SET nickname = 'x', role = 'admin' WHERE id = - The attacker's leading ' closes the nickname string; ", role = 'admin" adds a SECOND SET assignment that the developer never intended. - The WHERE id = still scopes it to their own row, so they quietly set their OWN role to admin -> privilege escalation. (If a password column exists, the same trick can set their own password, or — by manipulating the WHERE — someone else's.) (b) MODIFY EVERY ROW: Subvert the WHERE clause so it matches all rows. If id is numeric and injectable, set: id (input): 5 OR 1=1 Resulting query: UPDATE users SET nickname = 'x' WHERE id = 5 OR 1=1 - 1=1 is always true, so the WHERE matches EVERY user -> every user's nickname is overwritten with 'x'. The same pattern on a sensitive column (e.g. SET role='admin' ... WHERE id=5 OR 1=1, or SET password='known'...) would compromise or corrupt ALL accounts at once. - With a DELETE built the same way (DELETE FROM users WHERE id = 5 OR 1=1) you delete the entire table. WHY INJECTION INTO WRITES IS AN INTEGRITY/AVAILABILITY ATTACK (not just theft): - SELECT injection breaks CONFIDENTIALITY (read data you shouldn't). - INSERT/UPDATE/DELETE injection breaks: * INTEGRITY — the attacker CHANGES data: escalate roles, alter balances/ prices, reset passwords, falsify records. The data can no longer be trusted, even data that was never "leaked." * AVAILABILITY — the attacker DESTROYS data or service: DELETE rows, DROP tables (via stacking), or corrupt records so the application breaks. - So a write-side SQLi can take over accounts, commit fraud, or wipe the database — impacts that data-read defences (hiding output) do nothing about. It's frequently the pivot step after an initial read-based foothold. DEFENSIVE NOTE: Parameterizing the UPDATE — UPDATE users SET nickname = ? WHERE id = ? — binds both values as data: "x', role = 'admin" becomes a literal (weird) nickname string, and "5 OR 1=1" becomes an invalid id that matches nothing. Neither the extra SET nor the always-true WHERE can be injected. Plus least-privilege DB accounts (Chapter 8) limit damage if something slips.