Kuboid Secure Layer LogoKuboid Secure Layer
Back to Intelligence
February 24, 2026Vinay KumarIDOR

What Is IDOR? The Web Vulnerability That Exposes Your Users' Data

Cover Image for What Is IDOR? The Web Vulnerability That Exposes Your Users' Data

What Is IDOR? The Web Vulnerability That Exposes Your Users' Data

TLDR: I changed the number at the end of a URL from 1047 to 1046. Someone else's invoice appeared — their name, their address, what they bought, how much they paid. This is IDOR — Insecure Direct Object Reference — and I find it in roughly 60% of the web applications I test. It's not exotic. It's not complex. It's a logic error that occurs when an application trusts user input to determine what data to return, without verifying whether the requesting user is actually allowed to see it. This post explains exactly how it works, why scanners miss it, and how to fix it.


What IDOR Actually Is

IDOR stands for Insecure Direct Object Reference. The formal definition is dry: it occurs when an application uses user-controllable input to access objects directly, without performing adequate authorisation checks.

The plain-English version: your application lets users reference data by an ID — a number in a URL, a parameter in an API request, a field in a form — and then retrieves that data without confirming the requesting user is allowed to see it.

It's not a code syntax error. It's not a missing library. It's a missing question in the application's logic: "Does this user actually own what they're asking for?"

When that question isn't asked, any user who figures out the ID pattern can access any record in your system.


A Real-World Step-by-Step: How an Attacker Finds and Exploits It

Here's exactly what the discovery process looks like from an attacker's perspective — or a pen tester's.

Step 1: Log into the application as a normal user. Navigate to a page that displays personal data — your invoice, your profile, your order history.

Step 2: Look at the URL or open the browser's developer tools to inspect the API request. Notice a numeric identifier: GET /api/invoices/1047

Step 3: Change 1047 to 1046 and resend the request.

Step 4: If the application returns another user's invoice — names, addresses, financial data — without any authorisation error, the IDOR exists.

The entire discovery process takes under two minutes. No special tools required at this stage. No exploitation framework. Just curiosity and a browser.

From there, an attacker can automate it — writing a simple script to iterate through thousands of IDs, scraping every accessible record in the database. What started as one curious URL change becomes bulk data exfiltration.

This is why IDOR consistently ranks under Broken Access Control — the number one vulnerability in the OWASP Top 10 — and why it's been a top finding in bug bounty programmes for years.


Why Automated Scanners Miss It

Most development teams rely on automated security scanning — SAST tools, DAST scanners, dependency audits — as part of their pipeline. These tools are valuable. They do not catch IDOR. Here's why.

An automated scanner sees a request like GET /api/invoices/1047 and evaluates it for known vulnerability patterns: injection strings, dangerous functions, known CVEs. It doesn't have the context to know that 1047 belongs to User A, that 1046 belongs to User B, and that User A's session should only ever be able to retrieve 1047.

That context is business logic. It exists in your data model and your requirements document, not in the code syntax. IDOR is a logic error — the code works exactly as written. There's no syntax to flag, no dangerous function to detect. A scanner that receives 1046 in response to 1047 has no basis to call that a vulnerability unless it knows what those numbers mean.

This is precisely why manual penetration testing exists. A human tester, operating with understanding of the application's purpose, can reason about what a particular response means — and whether that meaning represents a security failure.


Real-World IDOR Findings From Bug Bounty Programmes

IDOR is consistently one of the most reported and highest-rewarded vulnerability classes on bug bounty platforms like HackerOne and Bugcrowd. A few documented examples illustrate the range of impact:

A researcher reported an IDOR in a major e-commerce platform's order API — by iterating through order IDs, they could access the name, address, email, and purchase history of any customer on the platform. The finding was rated high severity and rewarded accordingly.

In 2021, a bug bounty researcher discovered an IDOR in a healthcare application that exposed patient appointment records — including diagnoses and treatment notes — by manipulating appointment IDs in API requests. Healthcare data carries the highest regulatory penalties of any sector, and findings like this routinely result in significant fines under HIPAA or GDPR in addition to the breach response costs.

These aren't niche applications with amateur development teams. They're production systems built by experienced engineers under normal business conditions. IDOR is that pervasive.


The Most Common Places IDOR Appears

After hundreds of web application assessments, these are the areas where IDOR surfaces most reliably:

  • Invoice and order IDs in billing and e-commerce systems — sequential integers are a significant risk signal
  • User profile IDsGET /users/profile/2891 returning another user's personal data
  • Document and file IDsGET /documents/download/5512 without ownership validation
  • API endpoints using numeric foreign keys — especially in REST APIs where object IDs are passed directly as URL parameters
  • Password reset tokens and account confirmation links — if these use predictable or enumerable values
  • Admin operations that accept a user_id parameter — update, delete, and export endpoints are frequently vulnerable

The common pattern is sequential, numeric IDs passed as user-controlled input with no server-side ownership check. Anywhere that pattern exists in your application is a candidate for IDOR testing.


How to Test Your Own Application for IDOR

If you want to do a basic check before a formal assessment, here's a manual approach any developer can follow:

1. Create two test accounts in your own application — User A and User B.

2. Log in as User A and perform actions that generate object IDs: create an invoice, submit an order, upload a document, update a profile.

3. Note the IDs returned in the URLs, API responses, or network requests (visible in browser developer tools under the Network tab).

4. Log in as User B (in a different browser or incognito window) and directly request User A's objects using those IDs.

5. If User B receives User A's data without an authorisation error, the IDOR exists.

This test covers the horizontal privilege escalation case — same permission level, different user. Also test vertical escalation: can a regular user access admin-only endpoints by supplying IDs that admin functions operate on?


How to Fix IDOR

The fix is conceptually simple. The implementation requires discipline across the entire codebase.

Always perform object-level authorisation on every request. Before returning any object, the server must verify that the requesting user is the owner of — or has explicit permission to access — that object. This check must happen on the server side, every time, regardless of what the client sends.

// Vulnerable
const invoice = await Invoice.findById(req.params.id);
return res.json(invoice);

// Secure
const invoice = await Invoice.findOne({
    _id: req.params.id,
    userId: req.user.id  // ownership enforced at query level
});
if (!invoice) return res.status(403).json({error: 'Forbidden'});
return res.json(invoice);

Use non-sequential, non-predictable identifiers. UUIDs (e.g. 3f2504e0-4f89-11d3-9a0c-0305e82c3301) are significantly harder to enumerate than sequential integers. They don't eliminate the need for authorisation checks — a UUID is still a reference an attacker can try — but they remove the easy enumeration that makes mass exploitation trivial.

Implement object-level permission middleware. Rather than adding individual ownership checks to every controller, centralise authorisation logic into middleware or a permission layer that enforces ownership consistently across all resource-returning endpoints.

Audit every API endpoint. Map every endpoint that accepts an object reference as input and confirm that an authorisation check exists and is tested. This audit is often illuminating — teams regularly discover endpoints they'd forgotten were still in the codebase.


Think Your App Has IDOR? Let's Find Out.

IDOR is not obscure. It's not advanced. It's a systematic gap in authorisation logic that exists because development teams rarely have a formal process for asking "can this user actually access this?" at every layer of the application.

The good news: it's entirely preventable, and once the pattern is understood, your development team will start catching it themselves during code review.

If you want to know whether IDOR — or any of its access control cousins — exists in your application before a researcher or attacker finds it, a focused web application assessment is the fastest way to find out. We're happy to scope one around your specific stack and architecture.

Get in touch to start with a conversation, or explore our services to understand what an assessment covers. More technical posts like this are on the Kuboid blog.


Kuboid Secure Layer specialises in web application security assessments for product teams and startups. Learn more at www.kuboid.in or find out why founders work with us.

Vinay Kumar
Vinay Kumar
Security Researcher @ Kuboid
Get In Touch

Let's find your vulnerabilities before they do.

Tell us about your product and we'll tell you what we'd attack first. Free consultation, no commitment.

  • 📧support@kuboid.in
  • ⏱️Typical response within 24 hours
  • 🌍Serving clients globally from India
  • 🔒NDA available before any discussion
Loading form...