A01 Broken Access Control (+ course intro)
OWASP Top 10
Course 1 · Chapter 1 · A01: Broken Access Control
Welcome to a survey of the OWASP Top 10 — the web-security field's most widely-used map of the risks that matter most. Where the HTTPS, Authentication, CSRF, XSS, and SQL-injection courses each went deep on one problem, this course goes wide: ten categories that, together, cover most of what goes wrong in real applications — and where each one connects to the deep-dive you may already have done. We start at number one.
First: What the OWASP Top 10 Actually Is
The OWASP Top 10 is a periodically-updated awareness document published by the Open Worldwide Application Security Project, ranking the most critical web-application security risks. A few things to understand up front so you read it correctly:
- It's a risk ranking, not a checklist or standard. It tells you what to prioritize, not a complete list of everything to test. (OWASP's ASVS is the verifiable standard; the Top 10 is the awareness layer.)
- The categories are broad themes, each grouping many specific weaknesses (CWEs), not single bugs.
- It's data-driven plus a community survey — built from real-world vulnerability data across many organizations, with the current edition being 2021.
- The ranking shifts over time as the field changes — which is itself informative (Injection, long at #1, dropped to #3 in 2021 as frameworks improved; Broken Access Control rose to #1).
A01: Broken Access Control — The #1 Risk
Access control enforces what an authenticated user is allowed to do — it's authorization (the "what may you do?" from the Auth course, distinct from authentication's "who are you?"). Broken access control means those restrictions aren't properly enforced, so users can act outside their intended permissions: read others' data, modify records they shouldn't, or reach admin functionality. In 2021 it became the #1 category — found in a striking share of tested applications.
The Common Forms
| Form | What happens |
|---|---|
| IDOR (Insecure Direct Object Reference) | change an ID in the request (/account?id=124 → 123) and access another user's object |
| Vertical privilege escalation | a normal user reaches admin-only functionality (/admin, an admin API) |
| Horizontal privilege escalation | a user accesses another user's data at the same privilege level |
| Missing function-level access control | a sensitive endpoint isn't protected server-side — just hidden in the UI |
| Forced browsing | guessing/visiting unlinked URLs (/admin/deleteUser) that lack checks |
| Metadata/token tampering | editing a cookie, JWT claim, or hidden field (role=user → admin) |
Why It Tops the List
Two reasons. First, it's extremely common: access checks must be applied to every protected object and action, and missing just one is a hole — a large surface to get perfectly right. Second, the impact is severe: it leads directly to data breaches (reading every user's records by walking IDs), account takeover, and unauthorized administrative actions. It's also often trivial to exploit — no special tools, just changing a number or a role value in a request.
role field in the request, an isAdmin cookie, an ID the user can change — is not access control (the client is attacker-controlled). And "security through obscurity" — assuming an unlinked admin URL is safe because it's not in the menu — fails to forced browsing. Every access decision must be made server-side, based on the authenticated session's identity and permissions, on every request — never on anything the client sends or sees.
The Defences
- Deny by default — everything is forbidden unless explicitly granted; new endpoints are protected automatically, not accidentally public.
- Enforce server-side, every request — never rely on hidden UI, disabled buttons, or client-sent role/ID values.
- Check ownership on every object access — "does this user own/has rights to this record?", not just "is the user logged in?" (the IDOR fix).
- Centralize the access-control logic — one well-tested mechanism (middleware, a policy layer) rather than ad-hoc checks scattered and forgotten.
- Use a model — RBAC (roles) or ABAC (attributes) applied consistently; least privilege throughout.
- Make IDs hard to enumerate (defence in depth) — random UUIDs over sequential integers — but this supplements ownership checks, never replaces them.
- Log access-control failures and alert — repeated denials are a strong attack signal (ties to A09).
Hands-On Exercises
Classify each as the specific broken-access-control form (IDOR, vertical escalation, horizontal escalation, missing function-level control, forced browsing, token tampering): (a) changing ?userId=500 to read another profile; (b) a standard user POSTing to /admin/api/deleteUser; (c) editing a JWT's role claim to admin; (d) visiting an unlinked /reports/all that has no check.
Given an IDOR-vulnerable endpoint GET /api/invoices/:id that returns any invoice by ID, explain the attack and write the server-side ownership-check fix. Explain why using random UUIDs for IDs is helpful but not a substitute for the check.
Explain "deny by default" and why access control must be enforced server-side on every request. Then rebut three bad arguments: "the button is hidden for non-admins," "we check isAdmin from the cookie," and "that URL isn't linked anywhere." State the correct principle for each.
Chapter 1 Quick Reference
- OWASP Top 10 = a periodically-updated risk-awareness ranking (not a checklist/standard); current edition 2021; data-driven + community survey
- This course is the map; A02/A03/A07/A10 point back to your HTTPS/SQLi/XSS/Auth/CSRF deep-dives
- A01 Broken Access Control = the #1 risk (2021): authorization isn't enforced, so users act outside their permissions
- Forms: IDOR · vertical escalation · horizontal escalation · missing function-level control · forced browsing · token/metadata tampering
- Root mistake: trusting the client (role/ID values, hidden UI) or obscurity (unlinked URLs) instead of server-side checks
- Defences: deny by default · enforce server-side every request · check ownership per object (IDOR fix) · centralize · RBAC/least privilege · log failures
- Random UUIDs help (harder to enumerate) but never replace ownership checks
- Next chapter: A02 Cryptographic Failures — weak/missing encryption, plaintext, bad TLS & hashing (→ HTTPS & Auth courses)