OWASP Top 10 Overview
Meet the ten most common ways web apps get broken into — the shared vocabulary every backend engineer is expected to know.
You just shipped an API. It works, the tests pass, users are signing up. Then one morning you find someone reading other people's private messages — not by hacking anything clever, but by changing a 5 to a 6 in a URL. No alarms went off, because your code did exactly what you told it to.
Almost every breach that makes the news is a variation on a handful of mistakes that people keep making. Learn the pattern once and you'll spot it everywhere. That's what this whole course is for — and this lesson is the map.
The OWASP Top 10 (OWASP = the Open Worldwide Application Security Project, a non-profit) is the industry's ranked list of the most critical web app risks, refreshed every few years from real-world breach data. Think of it as the ten questions every code reviewer silently asks:
1. Broken Access Control — users reach data or actions that aren't theirs
2. Cryptographic Failures — sensitive data left unencrypted or weakly hashed
3. Injection (SQL, command) — untrusted input gets run as code
4. Insecure Design — the flaw is in the plan, not the typing
5. Security Misconfiguration — default passwords, debug mode left on
6. Vulnerable Components — an outdated library with a known hole
7. Authentication Failures — weak passwords, no brute-force protection
8. Data Integrity Failures — trusting data you never signed or checked
9. Logging & Monitoring Failures — the breach runs for months, unseen
10. Server-Side Request Forgery (SSRF) — your server fetches an attacker's URL
Don't memorise the numbers. Learn the shapes — every later lesson is one of these, up close.
What does Injection (OWASP #3) mean at its core?
- AUntrusted input reaches an interpreter and gets executed as code instead of treated as data
- BThe database injects extra rows into your query results
- CQueries run too slowly under heavy load
- DAn attacker guesses the database admin password
Let's make #1, Broken Access Control, concrete, because it's the one you'll write by accident. Picture a bouncer at a club. Checking that someone has a ticket is authentication. Checking the ticket is theirs and lets them into this room is access control — and it's the step people forget:
# VULNERABLE — any logged-in user can read any order by guessing the id
@app.get("/orders/{order_id}")
def get_order(order_id: int, db=Depends(get_db)):
return db.query(Order).filter(Order.id == order_id).first()
# SECURE — the order must belong to the caller
@app.get("/orders/{order_id}")
def get_order(order_id: int, user=Depends(get_current_user), db=Depends(get_db)):
order = db.query(Order).filter(
Order.id == order_id,
Order.user_id == user.id, # ← the ownership check
).first()
if not order:
raise HTTPException(404)
return orderThe first version authenticates (you're logged in) but never authorises (this is yours). Changing the URL from /orders/5 to /orders/6 walks you into someone else's data. This specific bug has a name — an IDOR (Insecure Direct Object Reference) — and it's the most common access-control flaw there is.
User A calls GET /orders/123, but order 123 belongs to User B. What should a well-built API do?
- AReturn 404 (or 403) — the order must not be readable by User A
- BReturn the order — anyone logged in can view any order
- CReturn 401 — force User A to log in again
- DRedirect User A to their own order list
The everyday name for the access-control bug where changing an id in the URL reveals another user's data is an ______ (four-letter acronym).
Your app depends on a Python package with a published CVE (a known, catalogued vulnerability). Which OWASP category is that?
- AVulnerable and Outdated Components (#6)
- BBroken Access Control (#1)
- CInjection (#3)
- DSecurity Misconfiguration (#5)
- The OWASP Top 10 is the shared, risk-ranked vocabulary of web attacks — every lesson ahead is one of its entries in detail.
- Broken Access Control (#1) is the one you'll write by accident: authenticating a user (who are you) is not the same as authorising them (is this yours). Always add the ownership check.
- An IDOR is the classic access-control bug — a guessable id with no ownership check. Fix: filter by resource id and caller id, and prefer 404 so you don't confirm the resource exists.
- Injection (#3) is data being run as code; Vulnerable Components (#6) is shipping a dependency with a known CVE.
Next: the first line of defence for almost all of these — never trusting what the client sends.