Glossary
What is IDOR — seeing someone else's data just by changing an ID
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 real defense (check on every request whether THIS user may access THIS object, server-side) — explained defensively, no attack steps.
"I changed id=124 to 125 in the URL and someone else's invoice appeared" — that's IDOR (broken access control). 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 gap | Result |
|---|---|
| Trusting the ID as-is after login | Swap to another user's ID and it sails through |
| "Not shown in UI = safe" mistake | Hitting the API directly is wide open |
| No permission check on create/update/delete | Not just viewing — tampering and deletion too |
Why it works
Defense: verify ownership/permission server-side, every time
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.
Deny by default
New endpoints start from "deny everything except what's explicitly allowed," so a forgotten check fails closed, not open.
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.
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.
This site's view: unglamorous, but maximum impact — guard it with tests
IDOR is technically dull and easily missed in code review, yet the impact is top-tier ("one click reveals everyone's personal data"). So the practical move is to lock in an automated test: as another user, hitting 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.
Read next
- Glossary: What is CSRF (authn vs authz)
- Basics: Security basics · Free security tools
FAQ
QWhat happens with IDOR?
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 flagship of the most common issue class (broken access control) and frightening because it needs no special tools.
QWhat's the top defense?
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?
They only make IDs harder to guess — not a real fix. If an ID leaks or is shared, it sails through. Keep randomization as a helper; the real defense is always a server-side ownership/permission check.