Skip to lesson
Exit
Application Security & Secure Code Review1 / 2

2 min lesson

The injection family

Compare two rows from "The injection family", then say when each one fits.

Step 1 of 2

The injection familyuntrusted data crosses into a different interpreter

Injection bugs share one root cause: data the attacker controls gets concatenated into a string that some interpreter then executes - SQL, a shell, an HTTP client, a template engine. The fix is always to keep data as data. Parameterize, don't interpolate.

Class
SQL injection
One-line root cause
User input concatenated into a query string
Paved-road fix
Parameterized queries / prepared statements; never string-build SQL
Class
Command injection
One-line root cause
Input passed to a shell that re-parses it
Paved-road fix
Pass argv arrays to exec, never a shell string; drop shell: true
Class
SSRF
One-line root cause
Server fetches a URL the attacker supplies
Paved-road fix
Allowlist destinations; block link-local/metadata IPs; resolve then validate
Class
Template injection
One-line root cause
User input rendered as template source, not data
Paved-road fix
Render with autoescaping on; never compile user strings as templates

Same shape every time: untrusted data treated as code in a second interpreter.

SQLi: the bug and the fix, side by side
q = f"SELECT * FROM users WHERE email = '{email}'"   # injectable
cur.execute("SELECT * FROM users WHERE email = %s", (email,))  # safe
Watch out

SSRF is the injection that hides in plain sight. "Fetch this webhook URL" or "import from this image link" lets an attacker point your server at 169.254.169.254 and read cloud metadata credentials. An allowlist of egress hosts beats any blocklist of bad IPs, because the blocklist always misses a representation (decimal IPs, DNS rebinding, IPv6-mapped).