What Is an IDOR Vulnerability?
An insecure direct object reference (IDOR) lets a user access data that is not theirs simply by
changing an identifier in a request. Change /invoice/123 to /invoice/124 and you see someone
else’s invoice — because the app confirmed you are logged in but never checked that this specific
record belongs to you. It is one of the most common and most damaging web flaws.
Why is IDOR so common?#
Because the missing check is invisible in normal use. Developers build a page that shows your data using your ID, test it as themselves, and it works perfectly. The bug only appears when someone substitutes a different ID — and the code, which checked authentication but not authorization, happily returns the other record. It is the textbook case of the authentication vs authorization gap.
How do you find and fix it?#
Finding it is a matter of changing identifiers and watching responses:
| Request | Vulnerable response | Secure response |
|---|---|---|
GET /invoice/124 (not yours) | 200 + the invoice | 403 / 404 |
POST /account/999/email | Changes another account | Rejected |
The fix is always the same — an object-level authorization check on every request:
On every request for object X:
confirm current_user is allowed to access X
else → deny (403/404), before returning anything
IDOR is the most common form of broken access control, the horizontal case of privilege escalation. More at the Web Security hub.
Frequently asked questions#
What is an IDOR vulnerability?
An insecure direct object reference occurs when an application exposes a reference to an internal object — like a database ID in a URL — and fails to check that the requesting user is authorized for that specific object. Changing /invoice/123 to /invoice/124 returns someone else’s invoice because the app checks login but not ownership.
How do you prevent IDOR?
Enforce authorization at the object level on every request: confirm the authenticated user actually owns or may access the specific record being requested, not just that they are logged in. Using unguessable identifiers helps a little, but the real fix is the ownership check — never rely on IDs being secret.