Learning Goals
3 minBy the end of this lesson you can:
- Explain what the OWASP Top 10 is and how to use it.
- Describe each category in one sentence with a real-world example.
- Map the categories to the deep-dive lessons coming up.
- Use the list as a checklist when reviewing or building a web app.
Warm-Up · A Shared Language for Web Risk
5 minOWASP (the Open Worldwide Application Security Project) publishes the Top 10: a periodically-updated, community-driven ranking of the most impactful web vulnerability categories, based on real-world breach data. When a security report says "an A03 issue," everyone knows it means injection.
The Top 10 is both a map of how web apps get hacked and a checklist. Most real breaches are not exotic — they're one of these ten, often the same few (broken access control, injection, misconfiguration). Knowing the list means you can audit any app systematically: "does it have an A01 problem? an A03 problem?" This tour is the overview; the next lessons drill the most important ones with live attack-and-defence pairs.
New Concept · The Ten Categories
14 minThe 2021 edition (the current widely-used list). Each is a category, not a single bug:
A01 Broken Access Control users reach things they shouldn't (the #1 risk) A02 Cryptographic Failures weak/missing encryption, leaked secrets A03 Injection untrusted input runs as code/query (SQLi, XSS*) A04 Insecure Design the flaw is in the design, not the code A05 Security Misconfiguration defaults, debug pages, exposed services A06 Vulnerable Components outdated/known-vulnerable libraries A07 Auth/Identification Failures weak login, session, credential handling A08 Software/Data Integrity unverified updates, supply-chain attacks A09 Logging/Monitoring Failures you can't detect or investigate an attack A10 Server-Side Request Forgery the server is tricked into making requests
(*In 2021 OWASP folded XSS into A03 Injection; many still teach it separately because the mechanism and defence differ.)
One example each (real-world flavour)
A01 changing ?user_id=123 to ?user_id=124 and seeing someone else's data A02 storing passwords as plain MD5; an expired TLS cert; a key in git A03 ' OR '1'='1 in a login form bypasses the password check A04 a "password reset" that emails the new password in plaintext, by design A05 a forgotten /debug page exposing config; default admin/admin A06 running a years-old library with a public, exploited CVE A07 no rate limit on login → credential stuffing; predictable session IDs A08 installing an update that wasn't signature-verified → backdoor A09 a breach goes unnoticed for 6 months because nothing was logged A10 give a URL field "http://169.254.169.254/" → server fetches cloud secrets
How to use the list
- As a builder: a checklist — design and review each feature against the relevant categories.
- As a reviewer/tester: a coverage guide — make sure your assessment touches all ten.
- As a communicator: shared vocabulary — "this is an A01" instantly conveys severity and class.
The road ahead in this level
L8-28 A01 Broken Access Control L8-29 A02 Cryptographic Failures L8-30 A03 SQL Injection — the ATTACK L8-31 A03 SQL Injection — the DEFENCE L8-32 A07/A03 XSS — the ATTACK L8-33 A07/A03 XSS — the DEFENCE L8-34 A05 Security Misconfiguration L8-35 A08 Software & Data Integrity (supply chain) L8-36 Challenge: OWASP Bug Hunt (find & patch them)
Every "attack" lesson is demonstrated against a deliberately vulnerable app you run locally (a tiny Flask demo, or OWASP Juice Shop / DVWA), and is immediately followed by the defence. The goal is never to attack real systems — it's to understand the mechanism well enough to write code that can't be exploited. Defender's mindset, always.
Worked Example · A Top-10 Self-Assessment Checklist
12 minGoal: a checklist tool that walks the Top 10 and, for a given app, records whether each category is addressed — turning the list into an actionable audit you can run on your own projects.
OWASP_2021 = [ ("A01", "Broken Access Control", "Every request checks the user is allowed to do/see this?"), ("A02", "Cryptographic Failures", "Passwords hashed (bcrypt)? TLS enforced? Secrets out of code?"), ("A03", "Injection", "All queries parameterised? All output escaped? No eval of input?"), ("A04", "Insecure Design", "Threat-modelled? Abuse cases considered? Safe-by-default flows?"), ("A05", "Security Misconfiguration", "Debug off in prod? Defaults changed? No exposed admin/services?"), ("A06", "Vulnerable Components", "Dependencies pinned + scanned? No known-vulnerable versions?"), ("A07", "Auth Failures", "Rate-limited login? Strong sessions? MFA? No default creds?"), ("A08", "Software/Data Integrity", "Updates/deps signature-verified? Lockfiles? CI integrity?"), ("A09", "Logging & Monitoring", "Security events logged? Alerts on anomalies? Logs protected?"), ("A10", "SSRF", "Server-side fetches validate/allow-list URLs? No internal access?"), ] def assess(app_name: str, answers: dict) -> None: print(f"OWASP Top 10 self-assessment — {app_name}\n") gaps = 0 for code, name, question in OWASP_2021: ok = answers.get(code, False) mark = "✓" if ok else "✗" if not ok: gaps += 1 print(f" [{mark}] {code} {name}") if not ok: print(f" → {question}") print(f"\n{10 - gaps}/10 addressed, {gaps} gap(s) to fix.") assess("my-blog", {"A01": True, "A02": True, "A03": True, "A05": False, "A07": True, "A09": False})
OWASP Top 10 self-assessment — my-blog
[✓] A01 Broken Access Control
[✓] A02 Cryptographic Failures
[✓] A03 Injection
[✗] A04 Insecure Design
→ Threat-modelled? Abuse cases considered? Safe-by-default flows?
[✗] A05 Security Misconfiguration
→ Debug off in prod? Defaults changed? No exposed admin/services?
...
4/10 addressed, 6 gap(s) to fix.Read the code
The checklist turns an abstract list into a concrete audit: for each category, a pointed question about your app, and a tally of gaps to close. Notice how the questions map to skills you already have or will get — A02 is the hashing/TLS lessons (9, 12-13); A03 is the SQLi/XSS pairs ahead; A09 is your log-analysis work (25). The Top 10 isn't trivia to memorise; it's the structure of every security review you'll ever do. Run this against your own Level 4 blog and you'll have a real to-do list.
Try It Yourself
13 minFor five real breaches you can recall or look up, classify each by OWASP category. Many map to A01, A02, A03, or A05 — note how concentrated real-world risk is.
Run the checklist against an app you built earlier (the Level 4 blog, the Level 5 LLM app, a Level 7 tool). Honestly mark each category and list the top 3 gaps to fix in this level.
Install OWASP Juice Shop (a deliberately vulnerable app, run locally via npm or Docker) or DVWA. Confirm it runs on localhost — this is your legal, safe target for the attack lessons ahead. Read its "this app is intentionally insecure" notice.
Hint
# OWASP Juice Shop (one command with Docker): # docker run --rm -p 3000:3000 bkimminich/juice-shop # then open http://localhost:127.0.0.1:3000 # It is BUILT to be hacked — legal and safe on your own machine.
Mini-Challenge · Map the Level to the Top 10
8 minBuild a small reference that maps each OWASP category to (a) the lesson(s) in this level that cover it, (b) the primary defence, and (c) one Python-specific way it shows up. This becomes your personal cheat sheet for the rest of Level 8 and beyond.
Show a sample mapping
A01 Access Control → L8-28,40 | defence: check ownership/role on every
request | Python: missing @login_required / no
"is this MY record?" check in a Flask view.
A02 Crypto Failures → L8-09,12-16,29 | defence: bcrypt + TLS + secrets in
env | Python: hashlib.md5(pw) for passwords (wrong!).
A03 Injection → L8-30-33 | defence: parameterised queries + output
escaping | Python: f-string SQL / Markup(user_input).
A05 Misconfiguration→ L8-34 | defence: debug off, change defaults, hide
services | Python: app.run(debug=True) in production.
A06 Vuln Components → L8-35 | defence: pin + scan deps (pip-audit) |
Python: an old requests/flask with a CVE.
A07 Auth Failures → L8-37-39 | defence: rate limit + strong sessions +
MFA | Python: no lockout on a login route.
A08 Integrity → L8-17,35 | defence: verify signatures, lockfiles |
Python: pip install from an untrusted index.
A09 Logging → L8-25,45 | defence: log security events + alert |
Python: bare except: pass that swallows attacks.Non-negotiables: each category mapped to its lesson(s), the primary defence, and a Python-specific manifestation.
Recap
3 minThe OWASP Top 10 is the industry's data-driven list of the most critical web-app risk categories — Broken Access Control, Cryptographic Failures, Injection, Insecure Design, Misconfiguration, Vulnerable Components, Auth Failures, Integrity Failures, Logging Failures, and SSRF. Most real breaches are one of these, often the same few. Use it as a builder's checklist, a tester's coverage guide, and a shared vocabulary. The next lessons drill the worst ones with live attack-then-defence pairs against deliberately-vulnerable apps you run locally — always to learn the defence. Set up Juice Shop/DVWA now as your safe practice target.
Vocabulary Card
- OWASP Top 10
- A ranked list of the most critical web-application security risks.
- broken access control (A01)
- Users reaching data/actions they shouldn't — the #1 risk.
- injection (A03)
- Untrusted input interpreted as code/query (SQLi, XSS, command).
- deliberately vulnerable app
- A practice target (Juice Shop/DVWA) built to be safely hacked.
Homework
4 minRun the OWASP self-assessment on a real app you built and produce a prioritised gap list. Build your category→lesson→defence cheat sheet. Stand up OWASP Juice Shop (or DVWA) locally and confirm it runs — you'll use it as the safe target throughout the attack lessons. Write a sentence on why having a local, intentionally-vulnerable app is the only ethical way to practise offensive techniques.
Sample · gap list + why a local target
Self-assessment of my Level 4 blog — top gaps:
1. A01: comment-edit route doesn't check the comment belongs to the
logged-in user → anyone can edit anyone's comment. (Fix: L8-28.)
2. A03: search uses an f-string SQL query → injectable. (Fix: L8-31.)
3. A02: passwords are SHA-256, no salt. (Fix: bcrypt, L8-13.)
Why a local vulnerable app is the only ethical practice: I need to
RUN real exploits to understand them, but doing that against any
system I don't own is a crime (L8-19). Juice Shop is built to be
hacked, runs on my own localhost, and explicitly invites it — so I
get genuine hands-on practice with zero legal or ethical risk.Non-negotiables: a real self-assessment with prioritised gaps, the cheat sheet, a running local target, and the ethics justification.