EXERCISE 2 — Stacked queries, and why the driver is a weak defence ================================================================== WHAT STACKED QUERIES ARE: - "Stacked" (or "piggy-backed") queries means sending MULTIPLE SQL statements in a single call, separated by a SEMICOLON. Where the database driver/API executes more than one statement per call, an attacker can APPEND an entirely separate command after the original one. - Unlike UNION (which must be a compatible SELECT bolted onto the original), a stacked statement can be ANYTHING — INSERT, UPDATE, DELETE, DROP, CREATE USER, even multiple statements — because it's a brand-new command, not part of the original query's structure. EXAMPLE — TURNING A SELECT INTO A DESTRUCTIVE COMMAND: Original: SELECT * FROM products WHERE id = $id Inject: id = 5; DROP TABLE users-- Resulting: SELECT * FROM products WHERE id = 5; DROP TABLE users-- - The first statement runs the harmless product lookup; the ; ends it and a SECOND statement (DROP TABLE users) executes, deleting the users table. - Other payloads: 5; UPDATE users SET role='admin' WHERE id=-- (escalate), 5; INSERT INTO users(...) VALUES(...)-- (create an account), etc. WHY '; DROP TABLE DOESN'T ALWAYS WORK: - Many widely-used driver/API combinations execute only a SINGLE statement per call by default, so the trailing "; DROP TABLE users" is rejected as a syntax/multi-statement error and never runs. Examples: * Classic PHP mysql_query / many MySQL client calls disallow multiple statements unless explicitly enabled. * Most PARAMETERIZED-query APIs send exactly one statement. - So the famous "'; DROP TABLE students; --" (the xkcd "Bobby Tables") is a great illustration but frequently fails in practice — which lulls people into thinking stacking isn't a threat. WHY "OUR DRIVER BLOCKS MULTIPLE STATEMENTS" IS A WEAK THING TO RELY ON: - It's CONFIGURATION-DEPENDENT and engine-dependent. Some stacks DO allow stacking (often SQL Server; PostgreSQL; MySQL with multi-statements enabled; certain connectors/ORMs). A library upgrade, a config flag, or a different code path can flip it on without anyone noticing. - It only addresses ONE technique. Even with stacking fully disabled, the query is STILL INJECTABLE: the attacker just uses in-band UNION/error-based, blind boolean/time-based, write-clause manipulation, or second-order delivery to read or modify data. Blocking stacking removes the most dramatic payload, not the vulnerability. - It's the wrong layer: you'd be depending on a defensive SIDE EFFECT of a driver setting rather than fixing the cause. - THE RIGHT RELIANCE: PARAMETERIZED QUERIES. They don't merely block stacking — they prevent the INJECTION that would attempt it, because the input is bound as data and "5; DROP TABLE users--" becomes a literal (invalid) id value that is never parsed as SQL. That closes stacking AND every other technique, regardless of driver flags. ONE-LINE TAKEAWAY: Stacked queries can append arbitrary destructive statements where the driver allows it; "; DROP TABLE often fails by luck of configuration, so never treat "multi-statements are off" as a defence — parameterize instead.