EXERCISE 3 — What an SQLi achieves, and why "sanitize the login form" is wrong ============================================================================== FIVE THINGS AN ATTACKER COULD ACHIEVE VIA A SINGLE SQLi (and what each needs): 1. READ ARBITRARY DATA (data theft). - Dump other tables: all users, password hashes, personal/payment data, often via UNION SELECT (Chapter 4) or blind inference (Chapter 5). - DEPENDS ON: a SELECT-context injection; the DB account's read access to the target tables (usually broad). The most common high-impact outcome. 2. BYPASS AUTHENTICATION (login bypass). - ' OR '1'='1 -style payloads make the login WHERE clause always true, returning a user row and logging the attacker in (often as admin) with NO valid credentials. - DEPENDS ON: the login query being injectable and trusting the row match for auth. (Ties to the Auth course: account takeover without a credential.) 3. MODIFY DATA (integrity attack). - Change prices, balances, roles (e.g. set your account to admin), or alter records via an injectable UPDATE, or by stacking an UPDATE. - DEPENDS ON: the injection reaching a write statement, or stacked-query support + INSERT/UPDATE privileges (Chapter 6). 4. DESTROY DATA / DENIAL OF SERVICE. - DELETE rows or DROP tables, or run expensive queries to exhaust the DB. - DEPENDS ON: stacked queries and DELETE/DROP privileges on the DB account (a key reason to use LEAST PRIVILEGE — Chapter 8). 5. ESCALATE BEYOND THE DATABASE (RCE / pivot). - Read/write server files, or execute OS commands via DB features (e.g. xp_cmdshell on misconfigured SQL Server, file functions, UDFs), then pivot into the internal network. - DEPENDS ON: an over-privileged DB account, dangerous features enabled, and DB/OS misconfiguration. Less common but catastrophic. (Also: out-of-band exfiltration via DNS/HTTP from the DB, reading information_schema to map the whole database, etc.) WHY "WE SANITIZE THE LOGIN FORM" IS AN INADEQUATE FRAMING: - It assumes SQLi only enters through one obvious input. In reality, INJECTABLE INPUT IS ANY DATA FROM OUTSIDE YOUR CODE that reaches a query: * URL query/path parameters (e.g. /product?id=5) * ALL form fields (search, profile, comments, filters) — not just login * HTTP headers (User-Agent, Referer, X-Forwarded-For) and COOKIES * JSON / XML API request bodies * File contents / uploads parsed into queries * SECOND-ORDER: data already STORED in the DB (e.g. a username saved earlier) that is later concatenated into another query (Chapter 6) — the payload arrives "from your own database," bypassing input-time checks entirely. - So "sanitize the login form" leaves dozens of other paths open, and second-order injection defeats input-time sanitization on principle. - Worse, SANITIZING/FILTERING input is the wrong defence anyway (the XSS blocklist lesson): you can't reliably enumerate every payload/encoding. - CORRECT FRAMING: treat EVERY value that flows into a query as untrusted, and defend at the QUERY layer with PARAMETERIZED QUERIES EVERYWHERE (Chapter 7), plus least privilege and validation as defence in depth (Chapter 8) — not by trying to clean one input box. ONE-LINE TAKEAWAY: One injectable parameter anywhere can read, bypass, modify, destroy, or escalate; defend every query path by parameterizing, not by sanitizing the login box.