Login
ChallengesLearn
Scoreboard
Teams
Profile

Preferences

Truesapiens

LearnAccess ControlIDOR: The Missing Check
Access Control·Lesson 1 of 12

IDOR: The Missing Check

Insecure Direct Object Reference — when the server trusts the client-supplied identifier without verifying ownership. Change one number, see someone else data.

Beginner10 min
Access ControlIDORWeb
Loading lesson…
NextPath Traversal

© 2026 Truesapiens.

Terms of ServicePrivacy PolicyCookie Policy

Insecure Direct Object Reference (IDOR) is a type of access control vulnerability that occurs when an application exposes a direct reference to an internal object — such as a database record, file, or resource — and fails to verify that the user is authorised to access it. The result is that any authenticated user can access data belonging to other users simply by changing a parameter value.

What you'll be able to do
  • Define IDOR and explain why it is an access control failure (CWE-639).
  • Demonstrate how changing an identifier in a URL or parameter can expose another user's data.
  • Identify real-world IDOR vulnerabilities and their impact on privacy and compliance.
  • Apply server-side ownership checks to prevent unauthorised data access.
Key terms
IDOR
Insecure Direct Object Reference — a vulnerability where an application exposes internal object references (IDs, filenames, keys) without verifying the requesting user is authorised (CWE-639).
Direct object reference
A reference to a resource — such as a database primary key, filename, or invoice number — that the application uses directly to locate and retrieve the object.
Ownership check
A server-side validation that confirms the authenticated user has the right to access the requested resource, typically by comparing a user ID from the session against a foreign key on the resource.
What is it?

When a parameter becomes a skeleton key

Imagine a web application that displays user profiles using URLs like /profile?user_id=5. If the server fetches the profile by that ID without checking who made the request, an attacker can change the number to user_id=6 and see another user's personal data — name, email, phone number, and more.

IDOR is not limited to numeric IDs. It applies to any direct object reference that a user can manipulate: UUIDs in API paths, email addresses in POST bodies, filenames in download endpoints, and invoice codes in billing portals. The vulnerability is not that the reference is predictable — even UUIDs are vulnerable if the server trusts the client to specify which resource to return. The bug is the absence of a server-side ownership check.

Data flow in an IDOR attack
Mini Map
Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.
Try it

Explore the employee portal

The sandbox below simulates a company intranet HR portal. You are logged in as employee #3. Try navigating between employee profiles by typing different IDs into the URL bar or using the arrow buttons. With the auth check disabled, you can read anyone's salary and contact details. Enable the auth check to see what a properly secured endpoint looks like.

prod/employees/1
intranet-portal
URL/employees/1
Logged in as Carol Smith (employee #3)
Real-world relevance

Facebook's “View As” IDOR (2018)

In 2018, a security researcher discovered an IDOR vulnerability in Facebook's “View As” feature — a tool that lets users preview how their profile looks to a specific friend. The feature accepted a friend ID parameter, but the server did not verify that the requested profile belonged to the current user. By manipulating the ID, an attacker could view any Facebook profile's non-public data, including phone numbers, email addresses, and private photos.

Facebook patched the issue after a bug bounty report, but the incident illustrates the core IDOR pattern — a user-supplied identifier used without an ownership check. IDOR vulnerabilities remain one of the most common access control flaws reported in bug bounty programs today, and they frequently appear in financial systems, healthcare portals, and SaaS platforms.

Mitigation

The fix: verify ownership server-side

The defense against IDOR is to never trust user-supplied identifiers without verifying that the authenticated user owns the requested resource. The session contains the user's identity; every database query that retrieves a user-specific object should include that identity in the WHERE clause.

javascriptvulnerable
// VULNERABLE - trusts the user-supplied ID
app.get('/api/profile/:id', async (req, res) => {
  const profile = await db.query(
    'SELECT * FROM profiles WHERE id = $1',
    [req.params.id],
  );
  res.json(profile.rows[0]);
});

// SAFE - verifies ownership against session
app.get('/api/profile/:id', async (req, res) => {
  const profile = await db.query(
    'SELECT * FROM profiles WHERE id = $1 AND user_id = $2',
    [req.params.id, req.session.userId],
  );
  if (!profile.rows[0]) return res.status(403).json({ error: 'Access denied' });
  res.json(profile.rows[0]);
});

Additional layers: use session-derived identifiers where possible (never ask the client for the current user's ID), avoid exposing database primary keys in URLs by using opaque identifiers or slugs, and enforce access control in a reusable middleware layer rather than in individual route handlers.

Further reading
  • CWE-639: Authorization Bypass Through User-Controlled Key(MITRE)
  • IDOR: Insecure Direct Object Reference (PortSwigger)(PortSwigger)
  • OWASP Top 10 - A01:2021 Broken Access Control(OWASP)
Key takeaways

What to remember

  • IDOR is an access control failure, not an encryption or authentication issue — the server trusts the client to specify which resource to return.
  • Changing a single parameter — ?user_id=5 to ?user_id=6 — is enough to expose another user's data.
  • UUIDs and other “unguessable” identifiers do not prevent IDOR. If the server trusts the client to choose the resource, the vulnerability exists.
  • The fix is a server-side ownership check: filter queries by the authenticated user's session ID, not just the client-supplied parameter.
  • Common IDOR targets include profile pages, invoice downloads, file uploads, messaging APIs, and administrative panels.

Knowledge check

0/3 answered · 0 correct
  1. 1.What makes a web endpoint vulnerable to IDOR?

  2. 2.Does switching from numeric IDs to UUIDs fix IDOR?

  3. 3.A developer writes: const profile = await db.query("SELECT * FROM profiles WHERE id = $1", [req.params.id]). What is the verdict?