EXERCISE 1 — Why parameterized queries stop SQLi at the root ============================================================= THE "PARSE BEFORE BIND" MECHANISM: - SQLi exists because, with concatenation, the query text and the user's input are the SAME STRING. The database parser reads that whole string, so a ' in the input can change the query's STRUCTURE (close a literal, add a clause). - A prepared statement separates the two phases: 1. PREPARE/PARSE: the driver sends the query TEMPLATE with placeholders (? or $1), and the database PARSES AND PLANS it WHILE THE PLACEHOLDERS ARE STILL EMPTY. The structure — which tables, which clauses, how many conditions, where each value goes — is fully determined at this point. No user value exists in the parsed query yet. 2. BIND/EXECUTE: the driver sends the VALUES separately. They are slotted into the already-parsed plan as PURE DATA. Parsing is OVER, so a value cannot introduce new SQL tokens — it can only fill a value slot. - Because parsing happens BEFORE the data is attached, input can never be interpreted as code. There is no breakout because there's nothing left to break out of — the grammar was finalized before the attacker's value arrived. VULNERABLE (concatenated) LOGIN QUERY: const q = "SELECT * FROM users WHERE username = '" + user + "' AND password = '" + pass + "'"; db.query(q); PARAMETERIZED FIX: db.query( "SELECT * FROM users WHERE username = ? AND password = ?", [user, pass] ); TRACE — username = ' OR '1'='1 : In the VULNERABLE version: The input is concatenated into the string, producing: SELECT * FROM users WHERE username = '' OR '1'='1' AND password = '...' The parser sees the attacker's quote as the CLOSING quote of the username literal, then reads OR '1'='1' as SQL LOGIC (always true). The WHERE matches every row -> auth bypass. The input became CODE. In the PARAMETERIZED version: The query "SELECT * FROM users WHERE username = ? AND password = ?" is parsed first, with two empty value slots. Then user = ' OR '1'='1 is BOUND to the first slot as a DATA VALUE. The database searches for a username LITERALLY EQUAL to the string ' OR '1'='1 — i.e. a user whose name is the 9-character text "' OR '1'='1". No such user exists, so the query returns no rows and login fails. The quote, the OR, the second quote are just characters in the data; they have ZERO syntactic power. The input stayed DATA. ONE-LINE TAKEAWAY: Prepared statements parse the query while placeholders are empty, then bind values as data — so ' OR '1'='1 becomes a harmless literal username, never SQL. The vulnerability is removed at the source, not filtered.