Key Takeaways
- IDOR = accessing other users' data via IDs
- BOLA = IDOR for API endpoints
- Check authorization on every data access
- UUIDs reduce but don't eliminate risk
Contents
1. What is IDOR?
Insecure Direct Object Reference (IDOR) occurs when an application exposes internal object references (like database IDs) and fails to verify that the user is authorized to access them. Also known as BOLA (Broken Object Level Authorization) in API contexts.
2. Attack Examples
Basic IDOR
# Original request (your data)
GET /api/users/1234/profile
# IDOR attack (other user's data)
GET /api/users/1235/profile
# Document access
GET /download?file_id=5001 → file_id=5002
# Order history
GET /orders/12345 → /orders/12346
IDOR Locations
- URL path parameters (/users/123)
- Query parameters (?id=123)
- POST body ({"user_id": 123})
- Headers (X-User-ID: 123)
- Cookies
3. Finding IDORs
# Look for:
# - Numeric IDs (1, 2, 3...)
# - Predictable patterns
# - UUIDs (still test them!)
# - Encoded values (base64, etc.)
# Common endpoints to test:
/api/users/{id}
/api/orders/{id}
/api/documents/{id}
/api/messages/{id}
/api/invoices/{id}
# Test with:
# 1. Another valid user's ID
# 2. Your ID ± 1
# 3. 0, 1, -1 (edge cases)
# 4. Admin IDs if known
4. Advanced Techniques
# Encoded IDs
GET /profile?id=MTIzNA== # base64(1234)
# Decode, modify, re-encode
# Hashed IDs
/document/abc123def456 # MD5 hash?
# Check if predictable: md5("1234")
# Wrapped IDs
{"data": {"user": {"id": 1234}}}
# Reference in arrays
{"ids": [1234, 5678]}
# Second-order IDOR
# Change email → admin notification → includes other user data
5. Testing Methodology
- Create two test accounts (attacker, victim)
- Perform actions as victim, capture IDs
- Try accessing victim's resources as attacker
- Test all methods: GET, POST, PUT, DELETE
- Check horizontal (same role) and vertical (admin) access
6. Real-World Impact
- Facebook: $10,000 - view any user's photos
- Uber: Access other drivers' data
- Shopify: $15,000 - access merchant data
- Financial apps: View other users' transactions
7. Prevention Strategies
Secure Implementation
// Vulnerable
function getProfile($userId) {
return $db->query("SELECT * FROM users WHERE id = ?", $userId);
}
// Secure - verify ownership
function getProfile($userId) {
$currentUser = getCurrentUser();
$profile = $db->query("SELECT * FROM users WHERE id = ?", $userId);
if ($profile['id'] !== $currentUser['id']) {
throw new UnauthorizedException();
}
return $profile;
}
8. Bug Bounty Tips
- Focus on actions with high impact (payments, PII)
- Test both read and write operations
- Check mobile app APIs (often less protected)
- Look for GraphQL with introspection
- Document clear impact in reports
FAQ
Do UUIDs prevent IDOR?
UUIDs make guessing harder but don't prevent IDOR if IDs leak (referrer, logs, emails) or if authorization isn't checked. Always verify authorization regardless of ID format.