Most IDOR write-ups stop at "change the ID in the URL and you get someone else's data." That's the easy part. The part that actually matters — proving it rigorously, ruling out the boring explanation, and turning it into a report someone can act on — usually gets skipped. I recorded a full walkthrough doing exactly that, end to end, against a deliberately vulnerable local training target. The bug A simple invoice endpoint, GET /invoices/:id. It checks that someone is logged in (401 if not), but never checks that the logged-in identity actually owns the invoice it's returning: js `invoices.find(inv => inv.id === Number(req.params.id)) // no invoice.owner === session.user check` Log in as any user, change the number in the URL, read anyone's invoice. Classic CWE-639 — Authorization Bypass Through User-Controlled Key, and it maps directly to: OWASP A01:2021 — Broken Access Control API1:2023 — Broken Object Level Authorization (BOLA) **What the walkthrough actually covers** The video isn't just "look, it's broken" — it's the full evidence chain a real assessment needs: Timestamp Phase 0:00 Capture two separate identities (alice, bob) 1:26:19 Prove cross-owner access live, in-browser 2:06:26 Pull raw request/response evidence from the network tab 2:52:04 Run a negative control — unauthenticated request, confirm 401 4:08:06 Confirm independently with an automated IDOR probe 6:12:03 Create a structured finding (CWE/OWASP/API mapping + evidence) 8:12:07 Structure the evidence for review 10:29:00 Export a report The negative control is the step people skip most often, and it's the one that separates "broken access control" from "there's just no auth at all" — an important distinction if you're writing this up for a real triager. **Why the control matters** Without it, you've only shown that an authenticated user can read someone else's data — you haven't ruled out the (much less interesting) possibility that the endpoint has no auth check whatsoever. Hitting the same endpoint with zero session and getting a clean 401 proves the app does enforce authentication — it just never enforces ownership. That's the difference between a one-line "missing auth" bug and a systemic authorization-model gap. **Fix** Load the object, then check ownership before returning it: `const invoice = invoices.find(inv => inv.id === Number(req.params.id)); if (!invoice || invoice.owner !== session.user) { return res.status(404).end(); // or 403 — avoid leaking existence via 401 vs 403 }` Every object access needs to be authorized, not just authenticated — that's the whole bug in one sentence. Try it yourself → https://github.com/sendwavehub/scan-target-demo-apps Windows Store https://apps.microsoft.com/detail/9pj0j7bk1m27?hl=en-US Web Site https://Sendwavehub.tech/en/apps/ai-security-studio-4 Enter fullscreen mode Exit fullscreen mode
Manually Proving and Documenting an IDOR (CWE-639) — A Full Walkthrough
Full Article
Original Source
Read the full article at Dev →KhanList aggregates and links to publicly available news content. We do not host full articles from third-party sources. Always verify important information with original sources.