Glossary

What is IDOR: a flaw that exposes other people's data when an ID is changed

IDOR (Insecure Direct Object Reference / broken access control) lets someone change an ID in a URL or parameter and reach data that isn't theirs. How it works, and the main defense (check on every request whether THIS user may access THIS object, server-side) — explained defensively, no attack steps.

Published 2026-06-10 Updated 2026-10-06 6 min read
On this page

IDOR (broken access control) is when changing id=124 to 125 in a URL shows someone else's invoice. Here's how it works and how to reliably prevent it (no attack steps).

Why it happens

Authentication (who you are) passes, but authorization (may you do this?) is missing. Authentication and authorization are different — being able to log in does not mean being allowed to see that data.

Common gapResult
Trusting the ID as-is after loginSwap to another user's ID and access succeeds
"Not shown in UI = safe" mistakeCalling the API directly is not blocked
No permission check on create/update/deleteNot just viewing — tampering and deletion too

Why it works

User A logs in → their invoice /invoice?id=124
change id to 125 (User B's)
↓ server only checks "125 exists"
no ownership check, so B's invoice is shown
Check only the ID's 'shape' without verifying ownership, and changing your ID to someone else's just works.

IDs don't only appear as ?id= in a URL. API paths (/api/orders/125), JSON bodies ("userId": 125), file download URLs and hidden form fields all need the same check — anywhere a value sent by the user picks which object to act on.

IDOR is one form of broken access control. It goes by several names and is easy to confuse with its neighbors.

TermWhat's missingExample
IDORPer-object ownership/permission checkUser A changes an ID and sees User B's invoice
BOLASame as IDOR (OWASP API Security's name)/orders/{id} in an API returns someone else's order
Function-level authorization flawPer-function permission checkA regular user can call an admin-only API
Broken authenticationThe "who are you" check itselfThe API can be called without logging in

In the OWASP Top 10, Broken Access Control (A01) is ranked first in the 2025 edition, as it was in 2021. In the API-focused OWASP API Security Top 10 (2023), BOLA is also first (API1:2023).

Real cases: other people's data visible after login

Two public-sector cases this site has covered were officially attributed to defects introduced during system updates, yet the outcome had the same shape as an authorization flaw: a logged-in user could reach data that wasn't theirs.

  • UK Companies House (March 2026): users logged in to WebFiling could, through certain actions, potentially see other companies' directors' home addresses and other details, and unauthorized filings were technically possible. The agency says it was a defect introduced in an October 2025 system update, not an external attack → full write-up
  • Japan's National Tax Agency e-Tax (September 2026): a defect from a My Page update let other users view gift-tax returns and related documents for 79 people → full write-up

In both, the login check worked. What was missing was "may this user act on this object?" And both happened after a change. Even a correct build can lose the check when a feature is added, which is why an automated test that runs every time is worth having.

Defense: verify ownership/permission server-side, every time

1

Check ownership/permission per object (most important)

Right before returning or modifying data, verify server-side that the logged-in user owns or is permitted that object. Deny if not.

2

Deny by default

New endpoints start from "deny everything except what's explicitly allowed," so a forgotten check fails closed, not open.

3

Query only 'your own' rows

Bake the owner condition into the query itself (e.g. filter by current user id). Route everything through one shared authorization helper so no call site forgets it.

4

Don't mistake UI control for defense

Hiding a button is UX, not security. Assume the API is called directly and decide only on the server. Keep random IDs as a helper, not the control.

How to check your own app

Do this only in an app you build or manage. Trying it on someone else's service can be unauthorized access.

  1. Create test users A and B, and give each one record (an order, a file, etc.)
  2. Logged in as A, call the view, update and delete APIs with an ID that points at B's record. Call the API directly from developer tools or an API client, not through the UI
  3. Confirm every request is refused with 403 or 404. Also check that list endpoints don't include B's records
  4. Turn this into an automated test, and add the same test whenever you add an endpoint

The OWASP API Security Top 10 likewise recommends writing tests that evaluate the authorization mechanism and not deploying changes that make those tests fail.

This site's view: easy to overlook but high impact, so check it with automated tests

IDOR is technically dull and easily missed in code review, yet the impact is severe ("one click reveals everyone's personal data"). So the practical move is to add an automated test: as another user, requesting someone else's ID must return 403. This site's principle is "never defend in the client UI; decide only on the server." Authorization should be enforced by a mechanism on every request — never left to human attentiveness.

Sources (primary)

  • OWASP Top 10:2025, "A01 Broken Access Control" — top10.owasp.org (ranking; the insecure direct object references example)
  • OWASP API Security Top 10 2023, "API1:2023 Broken Object Level Authorization" — api-security.owasp.org (prevention; testing recommendation)
  • MITRE CWE-639: Authorization Bypass Through User-Controlled Key — cwe.mitre.org
  • Sources for the two cases (Companies House and National Tax Agency announcements) are listed in each case write-up

Classification

CWE classifies the types of weakness behind vulnerabilities; MITRE ATT&CK classifies attacker techniques. Both are maintained by MITRE and widely used to label vulnerability reports and detection rules.

CWE™: Copyright © 2006–2026, The MITRE Corporation. CWE is a trademark of The MITRE Corporation. The MITRE Corporation hereby grants you a non-exclusive, royalty-free license to use CWE for research, development, and commercial purposes. Any copy you make for such purposes is authorized on the condition that you reproduce MITRE’s copyright designation and this license in any such copy. CWE Terms of Use

FAQ

QWhat happens with IDOR?
A

A logged-in user changes an ID in a URL or API (?id=124 to another value) and views, edits, or deletes someone else's invoice, order, personal data, or files. It's the typical example of the most common issue class (broken access control) and frightening because it needs no special tools.

QWhat's the top defense?
A

On every request, server-side, verify 'may THIS logged-in user act on THIS object?' Even if the ID is well-formed, check ownership/permission and deny if absent (deny by default). Never rely on client-side UI hiding.

QDo UUIDs or random IDs prevent it?
A

They only make IDs harder to guess; they are not a fix. If an ID leaks or is shared, the request still succeeds. Keep randomization as a helper; the main defense is always a server-side ownership/permission check.

QWhat's the difference between IDOR and BOLA?
A

They describe the same problem. IDOR is the long-standing web-app name; BOLA (Broken Object Level Authorization) is the name used in the OWASP API Security Top 10, where it is ranked first in the 2023 edition (API1:2023). Both mean the per-object authorization check is missing.

QHow do I test my own app for IDOR?
A

In your own app, create two test users, A and B. Logged in as A, request B's data by ID for view, update and delete, and confirm every request is refused (403 or 404). Call the API directly rather than going through the UI, and keep this check as an automated test.

QWhere does IDOR sit in the OWASP Top 10?
A

Under A01, Broken Access Control. It was ranked first in both the 2021 and 2025 editions, and OWASP lists 'permitting viewing or editing someone else's account by providing its unique identifier (insecure direct object references)' as an example.