Insecure Direct Object Reference is the most beginner-friendly serious bug class. No exotic payloads โ you just access data that should belong to someone else. Scanners miss it because it requires understanding what the IDs mean.
> Test only systems you're authorized to test. The examples below are from labs and authorized engagements.
What IDOR Actually Is
An app shows you your own order at:
GET /api/orders/1043
IDOR is when changing 1043 to 1044 returns someone else's order, because the server checked that the order exists but not that it's yours.
Where to Look
Any time the app references an object by an identifier you can see:
- URL paths:
/invoice/8842 - Query params:
?user_id=51 - Request bodies:
{"accountId": 1200} - Hidden form fields
The Hunting Method
- Create two accounts, A and B.
- As A, capture a request that returns A's data.
- Replace A's object ID with B's.
- Send it as A (A's session, B's ID).
- If you get B's data, that's IDOR.
The two-account setup is the whole trick โ it lets you prove access crossed a boundary.
Beyond Sequential IDs
Developers sometimes swap numeric IDs for UUIDs and call it fixed. It isn't โ UUIDs are harder to guess, but if one leaks (in a shared link, an email, a referrer header), the access control is still missing. Obscurity is not authorization.
Don't Forget Write Operations
Reading someone's data is bad. Modifying it is worse. Test PUT, POST, and DELETE with another user's ID too โ an IDOR on "delete account" is far more severe than one on "view profile."
Why It's Worth Learning First
IDOR taught me to think about authorization as separate from authentication. Being logged in isn't the same as being allowed. That distinction is behind a huge share of real breaches.
