Broken access control sits at the top of the OWASP Top 10 for a reason: it is both the most frequently found serious weakness in web applications and one of the hardest classes for automated tooling to detect. The flaw is rarely exotic. It is usually a missing server-side check on a request that looks perfectly ordinary.
What broken access control actually means
Authentication answers "who are you". Authorization — access control — answers "what are you allowed to do". Broken access control is any failure of that second question: a user acts outside their intended permissions.
The critical detail is that the request is usually well-formed and authenticated. There is no injection payload and nothing malformed for a signature-based tool to flag. The user simply asks for something they should not get, and the server hands it over.
The forms it takes
Most real findings fall into a handful of recurring shapes.
- IDOR (insecure direct object reference) — changing an identifier in a URL, form field or JSON body to reference another user's object.
- Missing function-level authorization — an admin-only endpoint that checks whether you are logged in but never whether you are an admin. Often the UI merely hides the button.
- Vertical privilege escalation — a standard user performing an administrative action, frequently by replaying a request captured from a higher-privileged role.
- Horizontal privilege escalation — reaching a peer's data at the same privilege level; the classic multi-tenant SaaS failure.
- Mass assignment — submitting extra fields such as
role=adminthat the server binds to the model without filtering. - Method and metadata tampering — bypassing a control by changing the HTTP verb, altering path case, or manipulating a client-supplied role header.
Why scanners miss it
An automated scanner has no idea what your application's rules are meant to be. It cannot know that user A should not see invoice 1044, because nothing about that response looks like an error — it is a valid HTTP 200 containing valid data.
Detecting the flaw requires understanding intent and comparing behaviour across at least two identities. That is a human task, which is why access control findings dominate manual penetration test reports while barely appearing in scanner output.
How to test it properly
- Enumerate roles and write down the intended permission matrix first — which role may perform which action on which object. Without this you cannot recognise a violation.
- Create at least two accounts per role so you can test both horizontal and vertical movement.
- Capture a full request as the higher-privileged user, then replay it with the lower-privileged session and compare responses.
- Test the API directly rather than through the UI. Front-end controls are cosmetic; only the server's decision matters.
- Vary the identifier type — sequential ids, UUIDs, slugs, tenant ids and file references all deserve testing.
- Re-test after fixes, because access control patches frequently address one endpoint while leaving siblings exposed.
How to fix it
The durable fix is architectural rather than a series of point patches.
- Deny by default. Every resource requires an explicit grant; anything not permitted is refused.
- Enforce server-side, once. Centralise the decision in middleware or a policy layer instead of scattering per-controller checks that drift apart.
- Bind objects to owners. Query by owner and id together, so a foreign id simply returns nothing.
- Never trust client-supplied role data. Derive privileges from the server-side session, not a header or a claim the user controls.
- Allow-list writable fields to eliminate mass assignment.
- Log access-control failures and alert on bursts — repeated denials are a strong enumeration signal.
Related from TechBiz Security
Sources & further reading
- OWASP Top 10 — A01 Broken Access Control
- PortSwigger Web Security Academy — Access control vulnerabilities
- OWASP Authorization Cheat Sheet
- CWE-639: Authorization Bypass Through User-Controlled Key
0 comments
Leave a comment