Quick reference for the OWASP Top 10 — each category with its cause, example, and one-line fix.
OWASPInjectionAccess ControlAppSec
OWASP Top 10 (2021) — Cause → Fix
| Category |
Typical cause |
One-line fix |
| A01 Access Control | Client-trusted IDs | Deny by default; scope queries to user |
| A02 Crypto Failures | Weak/no crypto | TLS 1.3, Argon2id, AES-GCM |
| A03 Injection | Input as code | Parameterized queries |
| A04 Insecure Design | No threat model | Threat model + abuse cases |
| A05 Misconfiguration | Defaults/verbose errors | Hardened baseline via IaC |
| A06 Vuln Components | Outdated deps | SBOM + CI dependency scan |
| A07 Auth Failures | Weak creds/no limits | MFA + rate limiting |
| A08 Integrity Failures | Unsigned code/deser. | Sign + verify; lock deps |
| A09 Logging Failures | No visibility | Central logs + alerting |
| A10 SSRF | Unvalidated URL fetch | Allowlist + block internal IPs |
Injection & Access Control Cluster
Detect
Error/timing changes on ', --, quotes |
| Sequential/guessable IDs in URLs & bodies |
| Same endpoint returns other users' data by ID swap |
| Hidden admin routes reachable without role check |
Prevent
| Parameterized queries / safe ORM everywhere |
| Server-side authz on every request; deny by default |
| Allowlist input validation; least privilege DB user |
| Automated owner/non-owner access tests in CI |
Crypto, Auth & Integrity Cluster
Detect
| HTTP / mixed content; missing HSTS |
| No account lockout / rate limit on login |
| Unsigned updates; deserialization of user data |
Prevent
| TLS 1.3 + HSTS; Argon2id password hashing |
| MFA, breach-list checks, rate limiting/backoff |
| Sign artifacts; pin deps with integrity hashes |
| Never deserialize untrusted data; use JSON + schema |
Parameterized Queries
Node (pg / mysql2)
db.query('SELECT * FROM users WHERE email = $1', [email]); // pg
conn.execute('SELECT * FROM users WHERE id = ?', [id]); // mysql2
Python
cur.execute("SELECT * FROM users WHERE email = %s", (email,))
# Django ORM: User.objects.filter(email=email) is safe by default
Java (PreparedStatement)
PreparedStatement ps = conn.prepareStatement(
"SELECT * FROM users WHERE email = ?");
ps.setString(1, email);
SSRF Guard
const ALLOWED = new Set(['images.example.com']);
const u = new URL(userUrl);
if (u.protocol !== 'https:' || !ALLOWED.has(u.hostname)) reject();
// Resolve DNS, reject 127.0.0.0/8, 10/8, 172.16/12, 192.168/16,
// 169.254.169.254 (metadata). Disable redirects. Require IMDSv2.
Vuln → Lab Tool Mapping
| Vulnerability |
Find it in a lab with |
| SQL / injection | Juice Shop, sqlmap (own lab), Burp Repeater |
| Broken access / IDOR | WebGoat, PortSwigger Academy, Burp (compare users) |
| Vulnerable components | npm audit, osv-scanner, Dependency-Check |
| Misconfiguration / headers | OWASP ZAP, nikto, browser DevTools |
| SSRF | PortSwigger SSRF labs, Burp Collaborator |
| Auth / session | DVWA, WebGoat, Burp Sequencer |
Authorized use only
Run these tools only against intentionally vulnerable apps you host or targets you are explicitly authorized to test. Never point them at third-party systems.