EXERCISE 2 — Least privilege: doesn't prevent SQLi, but limits the damage ========================================================================== WHY LEAST PRIVILEGE DOESN'T PREVENT SQLi: - Least privilege restricts WHAT THE DB ACCOUNT CAN DO, not whether the query is injectable. If the app concatenates user input, the injection still HAPPENS — the attacker can still inject whatever SQL the account is ALLOWED to run. - So a read-only account doesn't stop SELECT-based data theft of the tables it can read; it just stops the injection being used for things the account can't do. WHY IT IS STILL ESSENTIAL: - It determines the BLAST RADIUS. The same injection against a root/DB-owner account vs a tightly-scoped account is the difference between "read one table" and "dropped the database and ran OS commands." Least privilege turns catastrophic compromises into limited ones, and is a critical containment layer for the inevitable mistake. A READ-ONLY REPORTING ENDPOINT — privileges its DB account SHOULD have: - SELECT on ONLY the specific tables/views the report needs (e.g. orders, products) — and nothing more. - Ideally read from dedicated VIEWS that expose only the needed columns (no password hashes, no PII it doesn't need). - Its own dedicated account (separate from write services). Privileges it should NOT have: - NO INSERT / UPDATE / DELETE / DROP / ALTER / CREATE (it's read-only). - NO access to sensitive tables it doesn't use (users credentials, payment secrets) — not even SELECT. - NO FILE privilege / file read-write functions (LOAD_FILE, INTO OUTFILE, COPY ... TO/FROM). - NO ability to create users/roles or grant privileges. - NO dangerous extended features (xp_cmdshell on SQL Server, untrusted UDFs, COPY ... PROGRAM on Postgres). - NO multi-statement/admin rights beyond what's needed. HOW EACH RESTRICTION LIMITS A SPECIFIC EARLIER ATTACK: - STACKED '; DROP TABLE users-- (Chapter 6): Even IF stacking is enabled and the injection lands, a READ-ONLY account with no DROP/DELETE privilege cannot execute the destructive statement — the DROP is denied. The attack degrades from "wipe the DB" to "denied." (No INSERT/UPDATE likewise blocks role-escalation writes.) - FILE READ (Chapter 1 escalation, e.g. MySQL LOAD_FILE / INTO OUTFILE, out-of-band exfiltration via files): Without the FILE privilege / file functions, the attacker can't read server files (e.g. /etc/passwd, config secrets) or write a webshell to disk through the DB. Removes a key SQLi-to-server-foothold path. - xp_cmdshell / OS COMMAND EXECUTION (Chapter 1 RCE escalation): If the account can't invoke xp_cmdshell (SQL Server) / dangerous UDFs / COPY ... PROGRAM (Postgres), the injection cannot pivot to running operating-system commands. This is the rung from "database breach" to "server/network compromise"; removing it caps the damage at the DB layer. - READING SENSITIVE TABLES (Chapter 4 UNION extraction): If the reporting account has no SELECT on the users/credentials table, a UNION SELECT username,password FROM users-- simply errors with "permission denied" — the attacker can't dump data the account can't see, even though the query is still injectable. ONE-LINE TAKEAWAY: Least privilege won't stop the injection, but it decides how bad it gets: a read-only, table-scoped, FILE-less, no-cmdshell account turns a would-be full-server takeover into, at worst, exposure of a few non-sensitive tables — while you fix the real bug with parameterized queries.