Understanding IDOR: A Practical Guide for Bug Bounty Hunters
September 17, 2026

Understanding IDOR: A Practical Guide for Bug Bounty Hunters

Most IDOR findings start with a small experiment. You are looking at a URL such as /invoice/1043, you change the number, and the page loads — because the server trusted a value it should have verified. That simplicity is why IDOR is everywhere, and why so many reports get closed as informational when they deserved a payout.

What IDOR Actually Is

Insecure Direct Object Reference is an authorization failure, not an input validation one. The application takes a reference to an object — a numeric ID, a UUID, a filename, a tenant key — straight from your request and returns the underlying record without checking whether you are allowed to have it.

Two conditions have to line up for it to be exploitable. The reference must be guessable or obtainable, and the server must skip the ownership check. Only the second one is the bug. Predictable IDs behind a working server-side check are just a design choice, while an unguessable UUID with no check is still an IDOR — those identifiers leak constantly in exports, emails, and accounts you legitimately control.

Keep horizontal and vertical access separate. IDOR usually means user A reaches user B's object at the same privilege level. A normal user calling an admin function is a function-level access control issue. Programs sometimes bucket them together, but your report should be precise about which one you found.

Where It Hides in Real Applications

Anywhere a user refers to a thing they own, there is a place to look.

  • Sequential integers and dates. /orders/55120, ?statement=2024-03. The quickest to test and the most commonly accepted.
  • Encoded identifiers. Base64 and hex look intimidating until you decode them. MTA0Mw== is just 1043 with padding. Decode, change, re-encode, send.
  • UUIDs. Not a fix on their own. Hunt for the same object elsewhere: a search result, an activity feed, a shared link, an export file often hands you another user's UUID.
  • GraphQL and batch APIs. A single node(id:) query or a mutation with an id field can slip past controls the REST layer enforces correctly.
  • File and report handlers. Downloads, receipts, invoices and PDF exports frequently skip the middleware protecting the HTML view.
  • Multi-tenant keys. org_id, tenant_id, workspace_id in a body or a header. One tenant reaching another is a serious finding in B2B software.

A Manual Workflow That Works

Tools speed this up, but the reasoning is manual. This order keeps you honest.

  1. Map the objects. Walk the application and list every endpoint that reads or changes a specific record.
  2. Create two accounts on the same application, ideally with the same role and plan, so ownership is the only difference.
  3. Capture requests from account A in your proxy. Note the object IDs.
  4. Replay A's requests using B's session, changing nothing else. If B receives A's data, you have the core finding.
  5. Now swap only the ID, still as B. Compare response bodies, not status codes. A 200 with an empty or generic body is not a bug.
  6. Repeat across methods. GET is the headline; PUT, PATCH and DELETE turn it into something considerably worse.
  7. Try to move the reference. Some endpoints check the query string but not the JSON body, or trust a header, or accept extra fields such as {"id":1044,"role":"admin"} through mass assignment.
  8. Ignore UI-only protections. A hidden button or a disabled field means nothing if the endpoint is reachable.

Tools Worth Reaching For

Burp Suite handles most of the heavy lifting. Repeater for manual swaps, Comparer for spotting the two-byte difference between your record and someone else's, Match and Replace for rewriting IDs on the fly. Autorize is the one extension worth installing on day one: it replays your traffic with a lower-privileged session and flags responses that look identical, which is exactly the signal you want.

Once an issue is confirmed, a short script using curl or requests lets you walk a range of IDs and show the real scope in your report. Keep the enumeration minimal. Three or four objects prove the point; ten thousand prove you did not read the program's rules and will get your account suspended.

Turning "It Works" into Impact

A response that returns your own data is not a finding, and triagers see that mistake daily. Confirm the record belongs to the other account by comparing names, emails, addresses, or any field your second account cannot see. Screenshot both sides with the requests visible.

Then ask what an attacker would actually do with it. Reading a support ticket is minor. Reading a password reset token, an invoice with a full billing address, or a private document store is not. An IDOR that reaches a write or delete endpoint is worse again. If the leaked field feeds another flow — an email address enabling account enumeration and reset abuse — explain the chain, but mark it clearly as a chain rather than the primary bug.

Writing the Report

  • Title it precisely. "IDOR on GET /api/v1/documents/{id} allows any authenticated user to read other users' documents" beats "Broken access control".
  • State the prerequisites. One low-privileged account, no special permissions, no user interaction.
  • Give numbered steps a triager can follow in two minutes: two accounts, one session swap, one changed ID.
  • Include raw requests and responses. Redact other users' data but keep enough to prove ownership — a first name, the last four digits, a domain.
  • Suggest the fix. The server must verify that the requested object belongs to the authenticated user, on every method. Unguessable IDs are defence in depth, never the remedy.
  • Argue severity in their terms. What access is required, what data is exposed, whether write is possible, how many users are affected — without inventing numbers you cannot support.

Make It a Reflex

Next time you see an identifier in a request, do three things: drop the request into Repeater, send it with your second account, then change the number and send it again. That thirty-second habit finds more real bugs than any scanner will. Keep notes on every ID you encounter; endpoints you cannot test today often become testable once you have a second account or a leaked reference.

Test only accounts you own and stay inside the program's scope. If you are unsure whether an action is permitted, ask the program before you try it. An IDOR is a small bug to find and a serious one to report well, so do the boring part properly: prove the ownership boundary was crossed, show the impact plainly, and hand the team a fix they can ship today.

Photo: Tumisu / Pixabay

Previous Post

How to Write a Bug Bounty Report That Gets Triaged Fast

Next Post

The Pre-Report Checklist: 12 Things to Verify Before Submitting a Bug

Related Posts

About Us

Bug Hunter Journal

Bug Bounty

Notes from the front lines of bug hunting.

Read More

Latest Post

Understanding CVSS Scoring: How to Rate Your Bugs Like a Pro
Transitioning from IT Security to Full-Time Bug Bounty: A Realistic Roadmap
How to Automate Your Recon with Subfinder, httpx, and Nuclei
From Zero to P1: A Writeup of a Critical Authentication Bypass

Notes from the front lines of bug hunting.