Bug bounty hunters love chasing exotic vulnerabilities. SSRF chains. Prototype pollution. Race conditions in obscure auth flows. Meanwhile the people quietly paying their rent every month are doing something far less glamorous. They are finding IDORs.

Insecure Direct Object References. The bug where an application uses a user supplied ID to look up a resource and forgets to check whether you should be allowed to access it. They have been a known issue for well over a decade. They are also still everywhere.

The simplest possible example

Imagine an endpoint that loads your order history. The URL looks like this.

GET /api/orders/12345

Your order is 12345. So you decrement to 12344 and send the request again. If the server returns the previous user, that is an IDOR. The server trusted the ID without verifying ownership.

Trivial. Ancient. And shipping to production in 2026.

Why they refuse to die

Three reasons. First, every sprint adds new endpoints faster than security audits can catch up. Every release is a fresh attack surface. Second, microservice boundaries leak. Service A trusts that B authorized the request. B assumed A did. Neither actually checked.

Third, GraphQL. Per field authorization is a nightmare. Most teams get it wrong on at least one resolver. Find a target using GraphQL heavily and you have already filtered for opportunity.

The five IDOR patterns that pay

The first is sequential integer IDs. Spot any URL or API path with a plain number. Decrement, increment, see what happens. If you read a stranger user resource, you have a bug.

The second is UUID leakage. Teams convince themselves UUIDs are safe because they cannot be guessed. They are right about that. They are wrong about leakage. UUIDs end up in search results, public profile pages, shared comment threads, email previews. Once you find them in one place, try them in another.

The third is indirect IDOR. An endpoint takes a team_id. You are a member of team 7. You swap to team_id 8. The server checked you were logged in. It never checked you belonged to that team. Now you are reading another companys project list.

The fourth is mass assignment. An update endpoint accepts a JSON body with display_name. You add user_id and role to the JSON. Sometimes the server silently accepts them. The result is exactly as bad as it sounds.

The fifth is GraphQL object IDOR. Query by ID. No per field authorization check. You read another user email, phone, private documents. Full data leak from one query.

The hunting workflow that works

Always two accounts. Create user A and user B with different email aliases. Map every ID and UUID A produces. Switch to B session. Try every one of A IDs.

Document what comes back. Authorization errors are fine. A 200 OK with A data in B session is the bug.

Then escalate. Read only is a finding. Write or delete is bigger. Privilege escalation is the jackpot.

What gets paid

Read another user private data lands around three hundred to fifteen hundred dollars. Reading across organizations is one to five thousand. Modifying another user data is two to eight thousand. Privilege escalation via IDOR is five to twenty thousand. IDOR inside an admin only endpoint can land five to thirty thousand. These are real numbers from public reports.

How to not waste your time

Self referential IDOR is not a bug. Accessing your own resources via a different path proves nothing. Public resources are not IDOR. If a comment thread is meant to be public, reading it is not exploitation. Stale data from your own session is not IDOR.

Real IDOR means a clean session on account B, accessing data that belongs to account A, with neither account having any business relationship to the other.

Reports get closed for sloppy proof more often than for invalid findings. Take screenshots from a fresh browser profile. Save the raw HTTP request. Specify the impact in concrete terms. Not could be exploited. Can read any user invoice history.

Where to start tonight

Pick one program with a wide scope. Make two accounts. Open Burp. Hit every endpoint you can find that takes an ID. Replay each request swapping accounts. Note the responses.

You will not find a bug on night one. You probably will not find one on night three either. Somewhere in the second or third week, on a tired Tuesday at eleven at night, you will see a 200 response that should not exist. That is the moment everything changes.

The bug class is ancient. The money is current. Get to work.