What is an IDOR vulnerability?

3 min read Updated 2026-02-05

Insecure Direct Object Reference. A vulnerability where an application exposes internal object references (like database IDs) that attackers can manipulate to access unauthorized data.

Common in: REST APIs SaaS applications Multi-tenant systems File download endpoints User profile pages

Understanding IDOR

IDOR occurs when applications use user-controllable input to directly access objects (database records, files, etc.) without proper authorization checks. It's one of the most common vulnerabilities found in web applications and can lead to massive data breaches. The fix is simple - always check if the user is authorized to access the resource - but it's frequently forgotten.

Examples

  • Changing /api/invoices/123 to /api/invoices/124 to view another user's invoice
  • Modifying a user_id parameter in a request to access another account
  • Incrementing file IDs to download other users' uploads
  • Manipulating order IDs to view or cancel other customers' orders

How to Prevent

  • Always verify the authenticated user has permission to access the requested resource
  • Use UUIDs or other non-guessable identifiers instead of sequential IDs
  • Implement object-level authorization checks on every endpoint
  • Add the user constraint to database queries (WHERE user_id = ?)
  • Log and monitor access patterns for enumeration attempts
  • Use automated testing tools to detect IDOR vulnerabilities
  • Consider using indirect reference maps for sensitive resources

Code Examples

Vulnerable API Endpoint

The vulnerable code fetches any invoice by ID without checking ownership. The secure version ensures the requesting user owns the invoice.

Vulnerable
// VULNERABLE: No authorization check
app.get('/api/invoices/:id', async (req, res) => {
  const invoice = await Invoice.findById(req.params.id);
  res.json(invoice);
});

// Any authenticated user can access ANY invoice by changing the ID
// GET /api/invoices/123 → GET /api/invoices/456
Secure
// SECURE: Verify ownership before returning data
app.get('/api/invoices/:id', async (req, res) => {
  const invoice = await Invoice.findById(req.params.id);

  // Check if the invoice belongs to the authenticated user
  if (invoice.userId !== req.user.id) {
    return res.status(403).json({ error: 'Forbidden' });
  }

  res.json(invoice);
});

// Even better: Query with user constraint
app.get('/api/invoices/:id', async (req, res) => {
  const invoice = await Invoice.findOne({
    _id: req.params.id,
    userId: req.user.id  // Only find if owned by user
  });

  if (!invoice) {
    return res.status(404).json({ error: 'Not found' });
  }

  res.json(invoice);
});

File Download IDOR

Vulnerable
// VULNERABLE: Predictable file paths
app.get('/download/:fileId', (req, res) => {
  const filePath = `/uploads/${req.params.fileId}.pdf`;
  res.download(filePath);
});

// Attacker can enumerate: /download/1, /download/2, etc.
Secure
// SECURE: Use UUIDs and verify ownership
app.get('/download/:fileId', async (req, res) => {
  const file = await File.findOne({
    uuid: req.params.fileId,  // UUID instead of sequential ID
    ownerId: req.user.id       // Must belong to user
  });

  if (!file) {
    return res.status(404).json({ error: 'File not found' });
  }

  res.download(file.path);
});

Real-World Incidents

Facebook (Meta)

2019

IDOR vulnerability allowed attackers to view private friend lists of any Facebook user by manipulating GraphQL queries.

Impact: Private data of millions of users potentially exposed

Uber

2019

IDOR in driver document upload allowed accessing other drivers' documents by changing the driver ID parameter.

Impact: Personal documents (licenses, insurance) of drivers exposed

US Department of Defense

2020

Bug bounty hunter found IDOR allowing access to any service member's PII by manipulating a record ID.

Impact: $4,000 bounty paid, vulnerability patched

Worried about IDOR in your app?

Our security audits identify vulnerabilities like this before attackers do. Get expert manual review of your codebase.