Insecure direct object reference: change the ID, get someone else's data

An insecure direct object reference (IDOR) is an access control flaw: a request names an object by its identifier, such as an order number or a file name, and the application returns or changes it without checking that the caller is allowed to. Change /invoices/1041 to /invoices/1042 and another customer's invoice appears. Nothing in the request is malformed; the check that should have happened simply does not.

Section Web attacks Updated Weakness CWE-639

Quick facts

Short name
IDOR
Weakness
CWE-639: authorization bypass through user-controlled key
OWASP category
A01:2025 Broken Access Control, which names IDOR in its description (A01 page); see broken access control
In APIs
The same flaw is called broken object level authorization, API1:2023
Does a WAF stop it?
No. The request is valid; only the application knows who owns the object

Prevention follows the OWASP IDOR Prevention Cheat Sheet.

IDOR examples

  • Changing a number in the address. /account/orders/58213 shows any order once the number is changed.
  • Changing a hidden form field. A profile update sends user_id=774; sending another value edits another profile.
  • Downloading by file name. /files/statement-2026-09.pdf serves whoever asks, because the folder is not tied to an account.
  • Acting, not only reading. Cancelling, refunding or deleting by identifier is the same flaw with worse consequences.
  • Moving up, not across. Changing a role or account type field reaches administrator functions; this is vertical privilege escalation.

Reading another user's data is horizontal privilege escalation; reaching functions above your role is vertical. Both are covered on broken access control.

Why IDOR is so common

Applications are usually built screen by screen: the page that lists a user's orders shows only their orders, so the page that shows one order seems safe. But the second page can be called directly with any identifier, and if it trusts the identifier the protection on the first page means nothing.

Sequential numbers make the flaw easy to find, but random identifiers do not fix it. A long random ID only hides the object; once it leaks through a shared link, a log or another response, the missing check is just as exploitable.

WHAT ACTUALLY PROTECTS THE OBJECT EASY TO GUESS EXPLOITABLE IF AN ID LEAKS SAFE SEQUENTIAL IDS, NO CHECK RANDOM IDS, NO CHECK SEQUENTIAL IDS, OWNERSHIP CHECK RANDOM IDS, OWNERSHIP CHECK // the check is the fix; random identifiers only make guessing harder
// identifier type against an ownership check

Finding IDOR in your application

Automated scanners rarely find it, because a response with another user's data looks like a normal successful response. The reliable method is to test with two accounts: sign in as one, record every request that carries an identifier, then replay them as the other and see what comes back.

In logs, IDOR probing shows as one account requesting many identifiers in sequence, or identifiers that belong to other accounts. That pattern is worth an alert; it is also why limits on how many objects one user may request per minute make bulk extraction slower. The same testing approach applies to APIs; see API security testing.

How to prevent IDOR

  1. Check ownership on every request that names an object. On the server, for reads and for every action, not only on the screen that lists objects.
  2. Look objects up through the user. Query the current user's orders for this ID, rather than any order with this ID.
  3. Centralise the check. One authorisation layer that every handler uses is easier to get right than a check in each handler.
  4. Deny by default. A new endpoint should refuse until someone writes down who may use it.
  5. Use random identifiers as an extra layer. They slow guessing; they never replace the check.
  6. Test with two accounts in every release. Make cross-account access part of the regular test plan.

What a WAF can do about IDOR

Nothing that fixes it. A request for invoice 1042 has the same shape whether its owner sends it or a stranger does; telling the two apart needs the application's data about who owns what. A request filter does not have it.

Rate limits can make walking through thousands of identifiers slower and noisier, which shortens how long a flaw goes unnoticed. The flaw itself stays until the ownership check is written.

Questions

What is an insecure direct object reference?

An IDOR is a flaw where a request names an object by its identifier and the application returns or changes it without checking that the caller may access it, so changing the ID reaches someone else's data.

What is an IDOR attack example?

Changing /invoices/1041 to /invoices/1042 in the address bar and seeing another customer's invoice, or changing a user_id field in a form to edit another person's profile.

What CWE is IDOR?

CWE-639, authorization bypass through user-controlled key. In the OWASP Top 10:2025 it belongs to A01 Broken Access Control.

What is the difference between IDOR and BOLA?

They are the same flaw. IDOR is the older, general name; broken object level authorization, BOLA, is the name the OWASP API Security Top 10 uses for it in APIs.

Do random IDs prevent IDOR?

No. They make identifiers harder to guess, but once an ID leaks the missing ownership check is still exploitable. The check is the fix.