eastbaycyber

IDOR (Insecure Direct Object Reference): Definition, How It Works, and Where You’ll See It

Glossary 7 min read
EC
East Bay Cyber Editorial Team Reviewed 2026-05-16
Definition

IDOR (Insecure Direct Object Reference) is an authorization vulnerability where an application exposes a direct reference to an internal object (like a record ID, filename, or UUID) and fails to verify the requester is allowed to access that specific object.

IDOR (Insecure Direct Object Reference) is a broken access control and authorization vulnerability where a user can access (or modify/delete) another user’s resources simply by changing an identifier in a URL or API request—like switching /invoice/123 to /invoice/124. Because IDOR often leads directly to data exposure or account-impacting actions, it should be treated as a high-urgency finding in web application security and API security programs.

How IDOR works

IDOR happens when an application’s access control logic is incomplete or misplaced. The app might authenticate a user correctly (session, token, SSO), but then trusts the client-supplied object reference to decide what object to operate on—without a server-side check that the user is authorized for that object.

Typical flow

  1. A user requests a resource that belongs to them: - GET /api/invoices/1001
  2. The server looks up invoice 1001 and returns it, but doesn’t check ownership/permission.
  3. The user (or attacker) changes the ID: - GET /api/invoices/1002
  4. The server returns invoice 1002 even if it belongs to someone else.

The “direct object reference” can be many things: - Numeric IDs (/users/42) - UUIDs (/docs/550e8400-e29b-41d4-a716-446655440000) - Filenames/paths (/download?file=payroll.xlsx) - Nested object IDs (/orgs/10/projects/99/issues/7)

Important nuance: Using UUIDs or “unpredictable” IDs does not fix IDOR. It may reduce casual guessing, but it’s still broken authorization if the server doesn’t enforce access rules.

Why IDOR keeps appearing

IDOR is common because it’s easy to accidentally ship when: - Developers implement authentication early, but authorization is added later or inconsistently. - Teams rely on UI constraints (“users can’t click that”) instead of server enforcement. - Microservices and APIs grow quickly, with many endpoints and inconsistent policy checks. - Access control is implemented per-endpoint manually instead of centrally.

What it looks like “on the wire”

Common IDOR request patterns include changing a path parameter, query parameter, or JSON field.

GET /api/v1/profile?user_id=123 HTTP/1.1
Authorization: Bearer <token>

Change user_id=123 to another value.

PUT /api/v1/shipping-addresses/8812 HTTP/1.1
Authorization: Bearer <token>
Content-Type: application/json

{"address":"...", "city":"...", "postal_code":"..."}

If the server doesn’t confirm you can edit address 8812, it’s an IDOR with write impact.

Quick verification with curl (authorized testing only)

In a test environment (or with explicit authorization), validate access control by replaying the same request with a different object ID:

# Baseline request for your own object
curl -sS -H "Authorization: Bearer $TOKEN" \
  "https://app.example.com/api/invoices/1001" | jq .

# Attempt to access a different object
curl -i -H "Authorization: Bearer $TOKEN" \
  "https://app.example.com/api/invoices/1002"

Signs of IDOR: - 200 OK with another user’s data - 204 No Content on delete requests you shouldn’t be able to perform - 200 OK on update requests that modify objects you don’t own

What you want to see instead: - 403 Forbidden (authenticated but not authorized) - Or 404 Not Found if the app intentionally avoids confirming existence (authorization must still be enforced)

What to fix (server-side object authorization)

The fix is not “hide the ID.” The fix is: enforce authorization on every object access.

A minimal, common pattern (pseudocode):

invoice = db.get_invoice(invoice_id)

if invoice.account_id != current_user.account_id:
    return 403

return invoice

In larger systems, prefer centralized policy enforcement (middleware, service layer checks, policy-as-code) so you don’t rely on every handler getting it right.

Where you’ll see IDOR in real systems

You’ll most often run into IDOR in applications where there are many “objects” owned by different users, customers, or tenants, especially when those objects are accessed via predictable identifiers.

Common real-world scenarios

  • SaaS multi-tenant apps: viewing other customers’ tickets, invoices, or user lists by changing tenant_id, org_id, or resource IDs.
  • APIs used by mobile apps: mobile endpoints often expose object IDs plainly; if backend checks are weak, IDOR appears.
  • Customer portals: order histories, shipping details, statements, claims—any “my account” style resource.
  • Document/download features: download?documentId= or file= parameters that allow access to other users’ files.
  • Admin-ish endpoints accidentally exposed to users: endpoints intended for support staff but reachable with normal user tokens.
  • GraphQL APIs: querying nodes by ID and receiving data without enforcing field/object-level authorization.

Operational indicators (for defenders)

IDOR exploitation may show up as unusual access patterns, especially in APIs:

  • Many sequential IDs requested rapidly (enumeration):
  • /api/orders/10001, /api/orders/10002, /api/orders/10003
  • Repeated 403/404 interspersed with occasional 200 on different object IDs
  • A single user accessing objects across many accounts/tenants

Log patterns to watch

If you log request paths and authenticated user identifiers, you can build detections like: - High cardinality of object IDs per user per time window - Requests to resources outside the user’s normal tenant/account scope

Example (illustrative) log fields to ensure you have: - user_id / subject - tenant_id (resolved server-side) - resource_type and resource_id - decision (authorized/denied) if you have a policy engine

A simple mental model to prevent IDOR

If your app uses any request that includes an object identifier—path, query, or body—ask:

“If I change this identifier to another valid one, will the server still authorize it?”

If the answer is “yes,” you likely have an IDOR/BOLA issue and should treat it as a high-severity access control defect.

Practical next steps for teams

  • Inventory object-access endpoints: list every route that accepts an object ID and confirm an explicit authorization decision is made server-side.
  • Centralize authorization: middleware/policy engines reduce the odds of “one missed endpoint.”
  • Add automated tests: for each sensitive object, test “same user = allowed” and “different user = denied.”
  • Monitor for enumeration: rate-limit and alert on unusual sequences of object IDs.

For nearby concepts you’ll see in appsec writeups, review what an IOC is and how it’s used in investigations: what is an ioc. If you’re building an API security program, it also helps to understand how IDOR/BOLA fits into broader attack chains like supply chain compromise: what is a supply chain attack.

IDOR is fundamentally a server-side authorization problem, but good security hygiene reduces blast radius and helps teams respond faster:

  • For secure remote access during testing and incident response, consider a reputable VPN such as NordVPN: Check NordVPN pricing →.
  • For password management and stronger account security in engineering teams, consider 1Password: Try 1Password →.

This article may contain affiliate links. We earn a commission on qualifying purchases at no extra cost to you.

Related terms

Broken Access Control

The broader category; IDOR is one common manifestation. Broken access control includes missing checks, incorrect role logic, forced browsing, and privilege escalation paths.

BOLA (Broken Object Level Authorization)

Common in API security to describe IDOR-style failures at the object level (e.g., “can I access this specific order?”). In many discussions, BOLA and IDOR are effectively the same class applied to APIs.

BFLA (Broken Function Level Authorization)

Authorization failures at the function/endpoint level (e.g., non-admin users can call /api/admin/export).

Mass Assignment

When an API accepts more fields than intended (e.g., {"role":"admin"}) and updates protected properties. Different from IDOR, but often appears alongside weak authorization.

Forced Browsing

Accessing unlinked or hidden endpoints directly. Can combine with IDOR when the hidden endpoint also lacks object checks.

Horizontal vs. Vertical Privilege Escalation
Access Control Lists (ACLs) / RBAC / ABAC

Models used to implement authorization. IDOR indicates the model isn’t enforced consistently at the object access point.

Last verified: 2026-05-16

Disclaimer: This article may contain affiliate links. We earn a commission on qualifying purchases at no extra cost to you.