IDOR & access control
Broken Access Control is, year after year, the #1 risk in the OWASP Top 10. It
happens when the app fails to verify that the user is allowed to perform the action or
reach the resource they request. IDOR (Insecure Direct Object Reference) is its
best-known variant: a tamperable identifier (id, uuid, filename, key) and the server
doesn’t check that the object belongs to the requester.
GET /api/invoices/1001 -> your invoiceGET /api/invoices/1002 -> someone else's? (IDOR)It needs no payloads: just change a value. That makes it trivial to exploit and, at the same time, one of the most frequent and high-impact flaws, especially in APIs.
Threat model
Section titled “Threat model”Read/modify/delete other users’ data, access to admin functions, account takeover (a write IDOR on someone else’s email is usually direct ATO) and mass leakage if the endpoint allows enumeration.
Anatomy
Section titled “Anatomy”The root cause is trusting the client: hiding options in the UI, validating only on the front end, or assuming “if they know the ID, it’s theirs”. There are two distinct checks and both must be server-side, per request:
- Authentication: who are you? (session identity).
- Authorization: can you do this action with this object? (role + ownership).
Variants
Section titled “Variants”- Horizontal: access another same-level user’s resources (classic IDOR; in OWASP API = BOLA, Broken Object Level Authorization).
- Vertical: reach a higher role’s functions (normal user →
/admin; in OWASP API = BFLA, Broken Function Level Authorization). - Function-level: the UI hides the button, but the endpoint is still reachable; or the check is applied only at one step.
- Mass assignment: send extra fields (
role=admin) the binder accepts (see its own page). - Context/state-dependent: authorized in one flow state, not another.
Red Team
Section titled “Red Team”Discovery
Section titled “Discovery”- Two-account method (A and B): do an action as A and replay it with B’s session, swapping the identifier to A’s. If B gets in, it’s IDOR. Repeat the other way and across roles (normal vs admin).
- Look for identifiers everywhere: URL/path, query, body/JSON, headers,
cookies, and inside the JWT (claims like
user_id). - Try ID types: incremental (enumerable), leaked UUIDs in other responses/logs/emails, filenames, encoded IDs (base64/hash) that are still guessable.
- Vertical escalation: hit admin routes/methods as a normal user; try alternate
HTTP methods (
PUT,PATCH,DELETE), “hidden” endpoints, old API versions (/v1vs/v2) and debug panels. - Review multi-step flows: is authorization enforced at every step or only at the start?
By hand (automate the two-account method)
Section titled “By hand (automate the two-account method)”- In Burp, authenticate as A and save a request to one of their resources.
- Swap the ID for B’s while keeping A’s session → do you reach B’s data?
- Automate with Autorize (or AuthMatrix): you configure a second user’s cookies/token and the extension replays each request with that session, flagging green/red where the control fails. It’s the fastest way to cover the whole app.
Advanced techniques
Section titled “Advanced techniques”- Mass enumeration with sequential IDs (in an engagement, prove it with a few; don’t dump millions).
- GraphQL: nodes by global
id; try accessing other users’ nodes. - File/blob/signature references (download URLs, document tokens).
- Race conditions on ownership checks (see its page).
Tooling
Section titled “Tooling”Burp Suite (Autorize, AuthMatrix), ffuf for controlled ID enumeration, and
cross-session response comparison.
Impact and chaining
Section titled “Impact and chaining”Leakage of all users’ data, modification/deletion, escalation to admin and ATO. Chainable
with JWT (forge user_id), with enumeration (discover IDs) and with mass assignment
(write privileged fields).
Blue Team
Section titled “Blue Team”Detection
Section titled “Detection”- One account accessing many distinct objects in a short time (enumeration).
- Access to objects the user doesn’t own (requires logging identity + object + decision to detect it).
- Calls to admin endpoints by role-less accounts;
403→200transitions after parameter tampering.
Telemetry and sources
Section titled “Telemetry and sources”Application/API-gateway logs with identity + accessed object + authorization decision, and per-user metrics (unique objects accessed per minute).
Hardening
Section titled “Hardening”- Server-side authorization on every request, bound to the session identity (never to client parameters).
- Deny by default: every resource/function denied unless explicitly allowed.
- Check object ownership (
WHERE owner_id = :session) on top of role. - Centralize authorization (one middleware/policy, RBAC/ABAC) with automated per-role tests; don’t scatter copy-pasted checks across controllers.
- Indirect/unguessable references (UUID v4) as an extra layer, never a substitute for the control.
- Against mass assignment: allow-list bindable fields (DTOs).
Response
Section titled “Response”Review the attacker’s accesses, notify affected users per regulation (GDPR), fix the control (ownership + role), and deploy enumeration detection.
CVEs and real-world cases
Section titled “CVEs and real-world cases”- First American Financial (2019) — sequential document URLs exposed ~885 million financial records (broken access control / document IDOR).
- USPS “Informed Visibility” (2018) — an API with broken access control exposed data of ~60 million users.
- Parler (2021) — sequential post IDs allowed archiving practically all of the platform’s content.
- Peloton, Experian, T-Mobile and numerous mobile apps — BOLA/IDOR in APIs is among the most frequent and best-paid bug-bounty findings.
Broken Access Control is A01 of the OWASP Top 10. CVEs in NVD (https://nvd.nist.gov/vuln/search) and GitHub Advisories (https://github.com/advisories).
Testing checklist
Section titled “Testing checklist”- Two-account method applied to read and write.
- IDs tested in URL, body/JSON, headers and JWT.
- ID types tested (sequential, leaked UUID, encoded).
- Vertical escalation: admin endpoints/methods as a normal user.
- Multi-step flows validated at every step.
- Mass assignment tested (extra fields like
role). - Impact proven by accessing your second account’s resource (without touching real third-party data).