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).
This course is the map; your other courses are the territory
Several Top 10 categories are the subjects of your deep-dive courses: A02 Cryptographic Failures → HTTPS & password storage, A03 Injection → SQLi & XSS, A07 Authentication Failures → the Auth course, A10 SSRF → the CSRF course's SSRF section. For those, this course gives the overview and where-it-fits and points you back to the depth. The real new ground is the categories you haven't covered — starting right here with the one that tops the list.

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

FormWhat happens
IDOR (Insecure Direct Object Reference)change an ID in the request (/account?id=124123) and access another user's object
Vertical privilege escalationa normal user reaches admin-only functionality (/admin, an admin API)
Horizontal privilege escalationa user accesses another user's data at the same privilege level
Missing function-level access controla sensitive endpoint isn't protected server-side — just hidden in the UI
Forced browsingguessing/visiting unlinked URLs (/admin/deleteUser) that lack checks
Metadata/token tamperingediting a cookie, JWT claim, or hidden field (role=useradmin)
// IDOR — the endpoint trusts the id without checking ownership // GET /api/invoices/1043 (you're allowed to see YOUR invoice 1043) // GET /api/invoices/1044 → returns someone ELSE'S invoice. Broken access control.

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.

The root mistake: trusting the client, or relying on "they can't see the link"
Broken access control almost always comes from enforcing access in the wrong place — or not at all. Hiding a button in the UI is not access control (the attacker calls the API directly). Trusting a client-supplied value — a 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

Exercise 1

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.

📄 View solution
Exercise 2

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.

📄 View solution
Exercise 3

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.

📄 View solution

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)