What is Broken Authorization and Why It Matters
Broken authorization happens when an application correctly confirms who a user is but fails to enforce what that user is allowed to do, letting someone reach data or actions meant for another role or another account. It is distinct from broken authentication (proving identity): here the login may be perfectly valid, yet the access decision behind it is missing, incomplete, or trivially bypassed. Checking a site for it means testing whether permission rules actually hold on the server for every object, function, and endpoint — not just whether the UI hides a button.
Why it matters in practical terms — a few points most checklists skip:
- It is the single highest-ranked web risk. Broken Access Control sits at position #1 in the OWASP Top 10 (2021), ahead of injection and every other category (source: https://owasp.org/www-community/Broken_Access_Control). If you prioritise one class of flaw to hunt on a site audit, this is statistically the one.
- The API version is even worse. In the OWASP API Security Top 10 (2023), Broken Object Level Authorization (BOLA) is API1 and Broken Function Level Authorization is API5 — two of the ten slots belong to authorization failures, which matters because modern sites expose far more logic through APIs than through rendered pages (source: https://devsec-blog.com/2024/05/web-api-security-champion-part-ii-broken-authentication-owasp-top-10/).
- Authentication and authorization fail for different reasons. A site can pass a login/MFA review and still leak data, so these must be tested as two separate checks (source: https://knowledge-base.secureflag.com/vulnerabilities/broken_authorization/broken_authorization_vulnerability.html).
A concrete way to see the difference when you test a site: take a valid, logged-in session for a low-privilege user (User A) and replay A's own token against resources that belong to User B — for example, change /account/1024/invoice to /account/1025/invoice, or reuse an admin-only POST endpoint. Authentication never breaks in this test (the token is genuine), so only an authorization check on the server can stop it. If B's invoice comes back, you have broken authorization, and it is exactly this "swap the ID, keep the session" pattern that automated crawlers miss because the request looks legitimate (source: https://knowledge-base.secureflag.com/vulnerabilities/broken_authorization/broken_authorization_vulnerability.html).
One caution for anyone building a checking routine: detecting these flaws reliably needs at least two authenticated accounts with different privilege levels and a comparison of their responses, since a scanner with a single session cannot distinguish "allowed" from "should have been denied" (source: https://appcheck-ng.com/broken-authentication/).
Common Types of Broken Authorization Vulnerabilities
Broken authorization means a user can reach data or actions that should be blocked for their role or identity. When you check a site, it helps to test each type separately, because each has a different root cause and a different exploit path. Below is a practical breakdown you can turn into test cases.
1. Broken Object-Level Authorization (IDOR/BOLA) The server trusts an object identifier from the request without confirming the caller owns it. Typical checks:
- Swap
?id=1001for?id=1002and see if another user's record loads. - Change a UUID, order number, or filename in the URL, body, or header.
- Replay a request captured from Account A while logged in as Account B. This is the top-listed category in the OWASP Top 10 2021 for web apps (source: https://owasp.org/www-community/Broken_Access_Control), which is why object-ID checks should be your first pass on any authenticated endpoint.
2. Broken Function-Level Authorization
The UI hides an admin button, but the endpoint behind it never re-checks the role. Test by calling admin or privileged routes (/admin, DELETE /users/{id}, PUT /settings) directly with a low-privilege token. Guides on broken authorization confirm that missing server-side role enforcement is a core cause here (source: https://knowledge-base.secureflag.com/vulnerabilities/broken_authorization/broken_authorization_vulnerability.html).
3. Vertical privilege escalation A standard user gains admin-level rights. Look for:
- Hidden or guessable admin parameters (
role=admin,is_admin=true) accepted on profile-update calls. - Mass-assignment on JSON bodies that overwrite server-controlled fields.
4. Horizontal privilege escalation Same privilege level, but access to another peer's resources — invoices, messages, uploaded files. This overlaps IDOR but also appears in tenant-to-tenant leaks in multi-tenant SaaS.
5. Authorization vs. authentication confusion Weak session or token handling lets attackers assume an identity, which then defeats every authorization check downstream. Pentesting walkthroughs show how credential and session weaknesses become the entry point for unauthorized access (source: https://pentest-tools.com/blog/detect-broken-authentication), so validate session invalidation, token scope, and re-authentication on sensitive actions.
6. Metadata and token tampering
- JWTs with
alg: none, unsigned claims, or client-editablerolefields. - Cookies or hidden form fields carrying trust decisions (
account_type,verified). - CORS rules that reflect any
Origin, exposing authorized data to attacker sites.
7. Forced browsing / static-file exposure Direct requests to files or routes that are never linked in the UI but stay reachable. A link-and-URL crawler such as LinkChecker can enumerate reachable paths to feed this test (source: https://wummel.github.io/linkchecker/).
Testing tip: keep at least two accounts (one low-privilege, one peer) and one unauthenticated session, then replay each authenticated request across all three. If a request succeeds where it should fail, you have found a broken-authorization case worth confirming manually.
How Broken Authorization Differs from Broken Authentication
Authentication and authorization sit next to each other in every login flow, but they answer two different questions. Authentication proves who you are (credentials, MFA, session issuance). Authorization decides what you are allowed to touch after that proof is accepted. A site can pass every login test and still leak data, because a valid, fully logged-in user is exactly the person who exploits broken authorization.
The order matters when you test:
- Authorization checks assume a successful login — you attack as an authenticated user, not as an anonymous one.
- Broken authentication is exploited before or during session creation (weak passwords, credential stuffing, guessable session tokens, missing MFA), described in detail on https://appcheck-ng.com/broken-authentication/.
- Broken authorization is exploited after a good session exists: you change an object ID, a role parameter, or a URL and reach something that isn't yours (source: https://knowledge-base.secureflag.com/vulnerabilities/broken_authorization/broken_authorization_vulnerability.html).
A concrete contrast you can reproduce on your own site:
- Broken authentication test — try logging in with leaked or default credentials, or replay an old session token. Tooling and detection methods for this are covered at https://pentest-tools.com/blog/detect-broken-authentication.
- Broken authorization test (horizontal) — log in as User A, then swap the
user_id=1001in a request for1002. If you see User B's data, authentication worked perfectly and authorization failed. - Broken authorization test (vertical) — as a normal account, call an admin-only endpoint directly. A missing server-side role check exposes it even though the UI hides the button.
The severity ranking reflects this difference. In the OWASP Top 10 2021, Broken Access Control is ranked #1 (A01:2021) — the most common category — per https://owasp.org/www-community/Broken_Access_Control, while authentication weaknesses were reclassified as Identification and Authentication Failures, A07:2021, down from position #2 in the 2017 list, as discussed in https://devsec-blog.com/2024/05/web-api-security-champion-part-ii-broken-authentication-owasp-top-10/.
Practical takeaways for checking a site:
- Different fix layer. Authentication is fixed at the login and session layer; authorization must be enforced on every request, server-side, per object and per action.
- Different test account setup. Authorization testing needs at least 2 users with different roles (and ideally 2 accounts of the same role for horizontal checks); authentication testing can start with a single account.
- Different scanner blind spot. A link and login crawler such as https://wummel.github.io/linkchecker/ can confirm pages load, but it never verifies whether the logged-in user should have reached them — authorization gaps stay invisible to purely functional crawling.
Manual Techniques to Test for Broken Authorization
Broken authorization is not something you find by scanning a login form once — it lives in every request that returns data or performs an action. Because OWASP moved Broken Access Control up from the 5th position to #1 in its 2021 ranking, noting that its 34 mapped CWEs had more occurrences in applications than any other category (source: https://owasp.org/www-community/Broken_Access_Control), manual, per-request testing is where you actually catch it. Automated crawlers miss it because they don't understand who is allowed to do what. Below is a repeatable manual method.
Step 1 — Build an access matrix before you touch a request Create at least two accounts per role and map them against every sensitive endpoint:
- Roles down the rows:
anonymous,user-A,user-B(same role, different tenant),admin. - Endpoints/actions across the columns: view, edit, delete, export, approve.
- Mark the expected result in each cell first. Every deviation you observe later is a finding candidate.
Step 2 — Horizontal escalation (IDOR / BOLA) with the A/B pair
Log in as user-A, capture a request that references an object you own, then replay it as user-B:
- Increment or swap identifiers:
GET /api/invoices/1041→1042. - Try UUIDs harvested from other responses, not just sequential IDs.
- Replace tenant/org parameters in the body or headers (
X-Account-Id,org=). - Confirm the object truly belongs to another user before reporting — this separates a real break from your own duplicated data.
Step 3 — Vertical escalation
- Take an admin-only URL (e.g.
/admin/users) discovered from JS files or the admin session, then request it with a normal user's cookie. - Tamper with role indicators:
role=user→role=admin,isAdmin:false→true. - Test mass assignment by adding privileged fields the UI never sends.
Step 4 — Method and flow bypasses
- Swap HTTP methods on the same path: if
GET /orders/9is blocked, tryPUT,DELETE, orPOST. - Access step 3 of a multi-step workflow directly, skipping the authorization check performed in step 2 (force browsing).
- Replay a request after logout or with an expired/absent token to expose missing server-side enforcement — a scenario also flagged in web-API broken-authentication testing (source: https://devsec-blog.com/2024/05/web-api-security-champion-part-ii-broken-authentication-owasp-top-10/).
Practical tip: keep two browser profiles (or two Burp sessions) open side by side and diff the responses. If user-B receives the same 200 and payload as user-A for user-A's object, you have a confirmed broken-authorization case — no scanner required.
Automated Tools for Detecting Authorization Flaws
Automated scanners are strong at flooding an app with requests but weak at understanding intent — and authorization is pure intent. That gap is why raw scanner output almost always needs a second, session-aware pass. The most useful setup is not "one tool" but a pipeline built around multiple authenticated identities.
A practical tool stack for authorization testing
- DAST scanners with authenticated crawling (OWASP ZAP, Burp Suite) — feed them at least two valid sessions (e.g., a low-privilege and a high-privilege user) so they can replay one user's requests inside the other's session.
- Access-control replay/diff tools (Burp's Autorize, AuthMatrix) — the core technique: capture a privileged request, strip or swap the auth token, and flag responses that don't change to 401/403.
- API fuzzers for object-level checks (BOLA/IDOR) — iterate object IDs across accounts to catch horizontal escalation that crawlers miss.
- Link/endpoint discovery to build the request map first; a maintained crawler such as LinkChecker (https://wummel.github.io/linkchecker/) can enumerate reachable URLs before you point auth-diff tools at them.
Why you can't fully automate it
OWASP classifies Broken Access Control as the #1 web risk, reporting that 94% of tested applications had some form of broken access control, an average incidence rate of 3.81%, over 318,000 occurrences in the dataset, and 34 mapped CWEs (source: https://owasp.org/www-community/Broken_Access_Control). The scale is why scanners matter — but the same 34-CWE spread means many flaws are context-specific business rules a signature can't judge.
A repeatable method that beats "run the scanner"
- Enumerate every endpoint and parameter with an authenticated crawl.
- Record baseline responses for each role.
- Replay every privileged request under a lower-privileged (and an anonymous) session using an auth-diff tool.
- Treat any 200/302 that should have been 403 as a finding — including subtle cases where the status is 200 but the body is empty.
- Re-run the same replay set in CI so a new endpoint can't ship without an access-control check.
For the authentication layer that underpins these checks — token handling, session fixation, credential stuffing exposure — pair the above with the broken-authentication detection workflow described at pentest-tools (source: https://pentest-tools.com/blog/detect-broken-authentication), since a valid-but-stolen session defeats even perfect authorization logic.
Best Practices to Fix and Prevent Broken Authorization
Fixing broken authorization is not about adding more login checks — it is about controlling what an authenticated user is allowed to do. The reason this matters: OWASP moved Broken Access Control to the #1 position in its 2021 Top 10, ahead of injection and cryptographic failures (source: https://owasp.org/www-community/Broken_Access_Control). Treat the following as an enforcement checklist, not a wishlist.
1. Enforce authorization on the server, per request
- Never rely on hidden fields, disabled buttons, or client-side role checks — the browser is not a trust boundary.
- Re-verify object ownership on every request that reads or mutates data (this is how you kill IDOR / BOLA). If a request references
/api/orders/1043, confirm the session owns order 1043 before responding. - Deny by default: a route with no explicit authorization rule should return 403, not fall through to "allowed".
2. Centralize the decision, not the code
Scattered if role == admin checks are where broken authorization hides. Use one policy layer (middleware, a policy engine, or a claims-based gate) so every endpoint routes through the same decision point. This also makes the rules auditable — you can enumerate exactly who can reach what. The SecureFlag knowledge base groups these failures under vertical (privilege) and horizontal (peer-object) access, and both must be blocked at the same layer (source: https://knowledge-base.secureflag.com/vulnerabilities/broken_authorization/broken_authorization_vulnerability.html).
3. Harden the authentication layer that authorization depends on Broken authorization is often reachable because authentication is weak — this is tracked separately as A07:2021, Identification and Authentication Failures, ranked #7 in the OWASP Top 10 (source: https://devsec-blog.com/2024/05/web-api-security-champion-part-ii-broken-authentication-owasp-top-10/). Practical actions:
- Invalidate session tokens server-side on logout and on password change.
- Rotate identifiers so old tokens can't be replayed.
- Bind tokens to a session context (scopes/claims), not just to "logged in = true".
4. Test it the way an attacker would — a repeatable method to check your site
- Log in as a low-privilege user and capture a working request.
- Replay privileged endpoints (admin panels, other users' object IDs) with that low-privilege token — a
200 OKwhere you expected403is a finding. - Remove or tamper with the authorization header/cookie and confirm the endpoint refuses, not silently serves cached data.
- Fuzz sequential and predictable IDs to detect horizontal access gaps.
Reproduce these checks after every release, because authorization rules break during refactors, not at launch. Pair manual review with an automated scanner to catch regressions — see the broken-authentication detection walkthrough at https://pentest-tools.com/blog/detect-broken-authentication and the appcheck breakdown at https://appcheck-ng.com/broken-authentication/. As of 2026, wire this replay test into CI so a broken rule fails the build instead of shipping.
