← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

Insecure Direct Object Reference (IDOR)

security CWE-639 OWASP A1:2021 CVSS 7.5 PHP 5.0+ Intermediate

Also Known As

Insecure Direct Object Reference object reference vulnerability

TL;DR

A user accesses another user's data by changing an ID in a URL or request — no authorisation check performed.

Explanation

IDOR occurs when an application exposes internal object identifiers (database IDs, filenames) directly in requests and does not verify that the requesting user is authorised to access that object. Example: /invoice?id=1234 — incrementing the ID to 1235 returns another user's invoice. Prevention: always verify that the authenticated user owns or has permission to access the requested resource, server-side, on every request.

How It's Exploited

GET /api/orders/1337
# If order 1337 belongs to another user and there's no ownership check,
# attacker reads their private data by incrementing the ID

Diagram

flowchart TD
    USER2[Logged in as User 42] --> REQ3[GET /api/invoices/100]
    REQ3 --> CHECK2{Check: does user 42<br/>own invoice 100?}
    CHECK2 -->|no check!| RETURN2[Returns invoice 100<br/>belongs to user 99!]
    subgraph Fix3
        AUTH3[Authorisation check<br/>SELECT WHERE id=100 AND user_id=42]
        ZERO[0 rows = 404 Not Found<br/>never reveal resource exists]
    end
style CHECK2 fill:#f85149,color:#fff
style RETURN2 fill:#f85149,color:#fff
style AUTH3 fill:#238636,color:#fff

Common Misconception

Using UUIDs instead of sequential IDs prevents IDOR. UUIDs prevent guessing but not IDOR — if authorisation checks are missing, an attacker who obtains any valid UUID can still access it freely.

Why It Matters

IDOR lets attackers access any user's data by simply changing an ID in the URL or request body. It is one of the most common API vulnerabilities because it is invisible to automated scanners and requires no special tools to exploit.

Common Mistakes

  • Assuming sequential IDs are "hard to guess" — automated tools enumerate thousands of IDs per second.
  • Checking authentication but not ownership — verifying a user is logged in does not verify they own the resource.
  • Using UUIDs and believing that makes IDOR impossible — obscurity without authorisation checks is not security.
  • Only protecting read endpoints and forgetting update and delete routes.

Code Examples

✗ Vulnerable
// No ownership check — any user can view any order
public function show(int \$orderId): JsonResponse {
    return response()->json(Order::findOrFail(\$orderId));
}
✓ Fixed
public function show(int \$orderId): JsonResponse {
    \$order = Order::findOrFail(\$orderId);

    // Enforce ownership — compare to authenticated user
    if (\$order->user_id !== auth()->id()) {
        abort(403); // Forbidden — not just 404
    }

    return response()->json(\$order);
}

// Or scope query to current user (prevents the object being fetched at all)
\$order = auth()->user()->orders()->findOrFail(\$orderId);

Added 13 Mar 2026
Edited 22 Mar 2026
Views 33
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 1 ping M 0 pings T 0 pings W 0 pings T 4 pings F 1 ping S 0 pings S 2 pings M 2 pings T 1 ping W 0 pings T 0 pings F 0 pings S 0 pings S 1 ping M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 1 ping M 0 pings T 0 pings W 0 pings T
No pings yet today
No pings yesterday
Ahrefs 9 Perplexity 8 Amazonbot 7 Unknown AI 3 Majestic 1 Google 1
crawler 28 pre-tracking 1
DEV INTEL Tools & Severity
🟠 High ⚙ Fix effort: Low
⚡ Quick Fix
After loading a resource by ID, always check: $resource->user_id === auth()->id() — never trust that the ID alone grants access
📦 Applies To
PHP 5.0+ web api
🔗 Prerequisites
🔍 Detection Hints
->find($_GET['id']) or findOrFail($id) with no subsequent ownership check
Auto-detectable: ✗ No semgrep
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: Medium ✗ Manual fix Fix: High Context: File Tests: Update
CWE-284 CWE-639

✓ schema.org compliant