Opening Framing: The Authorization Problem
Authentication verifies who you are. Authorization determines what you can do. Many applications nail authentication but fail catastrophically at authorization. They verify that you're logged in but don't verify that you should access the specific resource you're requesting.
Broken Access Control is #1 on the OWASP Top 10 for 2021— and for good reason. It's prevalent, impactful, and often trivial to exploit. Changing a user ID in a URL from your ID to another user's ID shouldn't reveal their data, but frequently it does.
This week covers access control vulnerabilities, Insecure Direct Object References (IDOR), privilege escalation, and the systematic approach to finding authorization flaws.
Key insight: Every request with a user-controlled identifier is a potential IDOR. Test them all.
1) Access Control Fundamentals
Understanding authorization models:
Access Control Types:
Vertical Access Control:
- Different user types have different privileges
- Admin vs. regular user
- Manager vs. employee
- Bypassing = privilege escalation
Horizontal Access Control:
- Same privilege level, different resources
- User A can't access User B's data
- Bypassing = IDOR
Context-Dependent Access Control:
- Access depends on state/workflow
- Can't skip steps in a process
- Can't access after deadline
- Bypassing = business logic flaws
Common Access Control Models:
Role-Based Access Control (RBAC):
- Users assigned to roles
- Roles have permissions
- Most common model
Permissions:
Admin: read, write, delete, admin
Editor: read, write
Viewer: read
Attribute-Based Access Control (ABAC):
- Decisions based on attributes
- User attributes, resource attributes, environment
- More flexible, more complex
Example policy:
IF user.department == resource.department
AND user.clearance >= resource.classification
THEN allow
Discretionary Access Control (DAC):
- Resource owner controls access
- Can share with others
- File system permissions
Mandatory Access Control (MAC):
- System enforces rules
- Users can't change permissions
- Military/government systems
Where Access Control Fails:
Common Failure Points:
1. Client-side only enforcement
- JavaScript hides buttons
- Server doesn't check
2. Security through obscurity
- Long/random URLs
- No actual access check
3. Inconsistent enforcement
- GET endpoint protected
- POST endpoint not protected
4. Missing checks on identifiers
- User ID in URL not validated
- Order ID accessible to anyone
5. Parameter manipulation
- role=user → role=admin
- isAdmin=false → isAdmin=true
6. Forced browsing
- /admin accessible without login
- API endpoints unprotected
Key insight: Access control must be enforced server-side, on every request, for every resource.
2) Insecure Direct Object References (IDOR)
The most common access control vulnerability:
IDOR Concept:
Application uses user-controlled input
to access objects directly:
/api/users/123/profile → User 123's profile
/api/users/124/profile → User 124's profile
If no authorization check:
Changing 123 → 124 reveals another user's data
IDOR = Direct reference + No authorization check
IDOR Locations:
URL Parameters:
/user?id=123
/profile/123
/api/v1/users/123
/download?file=report_123.pdf
POST/PUT Body:
{"user_id": 123, "action": "delete"}
{"account": "ACC123", "transfer": 1000}
Headers:
X-User-ID: 123
Cookie: user=123
File Names:
/documents/user_123_report.pdf
/uploads/invoice_123.pdf
API Endpoints:
GET /api/orders/ORD-123
DELETE /api/comments/456
PUT /api/profiles/789
Testing for IDOR:
Testing Methodology:
1. Create two test accounts
- User A (attacker)
- User B (victim)
2. Map all endpoints with identifiers
- User IDs
- Order IDs
- Document IDs
- Any reference
3. With User A's session:
- Request User B's resources
- Change ID parameters
- Observe response
4. Check for:
- Data disclosure (view other's data)
- Modification (change other's data)
- Deletion (remove other's data)
# Burp workflow:
1. Log in as User A
2. Capture request with User A's ID
3. Send to Repeater
4. Change to User B's ID
5. Does it return User B's data?
IDOR Variations:
# Sequential IDs (easiest)
/user/1, /user/2, /user/3
Enumerate all users
# UUIDs (harder but not secure!)
/user/550e8400-e29b-41d4-a716-446655440000
UUIDs are not secret if leaked anywhere
# Encoded IDs
/user/MTIz → base64("123")
Decode, modify, re-encode
# Hashed IDs
/user/a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3
If hash is predictable (MD5 of sequential), enumerate
# Indirect references
/user/current → returns your data
/user/current?impersonate=123 → hidden parameter?
# Composite references
/org/1/user/123
Try: /org/2/user/123 (cross-tenant)
Key insight: Any identifier in a request is potentially vulnerable. UUIDs and encoding are not access control.
3) Privilege Escalation
Vertical access control bypass:
Privilege Escalation Types:
Vertical:
Regular user → Admin
Employee → Manager
Reader → Editor
Horizontal to Vertical:
Access another user's admin account
Access service account with higher privileges
Testing for Privilege Escalation:
# Access admin endpoints as regular user
1. Map admin functionality
- Browse as admin, note URLs
- /admin/*, /manage/*, /dashboard/*
2. Access as low-privilege user
- Same URLs
- Same API endpoints
# Common admin endpoints to test:
/admin
/admin/dashboard
/admin/users
/admin/settings
/api/admin/users
/api/v1/admin/*
/manage
/management
/console
# Use Burp:
1. Browse as admin, capture all requests
2. Log in as regular user
3. Replay admin requests with regular user's session
4. Check if access granted
Parameter-Based Privilege Escalation:
# Role/privilege in request
# Hidden form field:
<input type="hidden" name="role" value="user">
Change to: role=admin
# Cookie:
Cookie: role=user; session=abc123
Change to: role=admin
# JSON body:
{"username": "newuser", "role": "user"}
Change to: {"username": "newuser", "role": "admin"}
# JWT payload:
{"user": "john", "role": "user"}
Modify to: {"user": "john", "role": "admin"}
(if signature not validated)
# Query parameter:
/profile?admin=false
Change to: /profile?admin=true
# Header:
X-Admin: false
Change to: X-Admin: true
Function-Level Access Control:
# Different HTTP methods
# GET might be protected:
GET /admin/users → 403 Forbidden
# But POST isn't:
POST /admin/users → 200 OK (creates user!)
# API endpoints:
GET /api/users/123 → Your data only
DELETE /api/users/123 → Deletes any user!
# Test all methods:
GET, POST, PUT, PATCH, DELETE, OPTIONS
# Method override:
X-HTTP-Method-Override: DELETE
X-Method-Override: DELETE
_method=DELETE
Key insight: Just because you can't see admin functionality doesn't mean you can't access it directly.
4) Business Logic Flaws
Exploiting flawed application logic:
Business Logic vs Technical Vulnerabilities:
Technical: SQL injection, XSS
- Well-defined patterns
- Automated scanning helps
Business Logic: Flawed assumptions
- Application-specific
- Requires understanding the business
- Manual testing essential
Common Business Logic Flaws:
# Price Manipulation
Original: {"item": "laptop", "price": 999.99}
Modified: {"item": "laptop", "price": 0.01}
# Quantity Manipulation
Original: {"item": "gold", "quantity": 1}
Modified: {"item": "gold", "quantity": -10}
Result: Negative total = credit to account?
# Coupon/Discount Abuse
- Apply same coupon multiple times
- Apply coupon after checkout started
- Stack incompatible discounts
# Workflow Bypass
Normal: Step1 → Step2 → Step3 → Complete
Attack: Step1 → Step3 → Complete (skip verification)
# Race Conditions
- Submit same request simultaneously
- Withdraw money twice before balance updates
- Apply limited coupon multiple times
# State Manipulation
- Complete order, then cancel, keep items
- Upgrade trial, downgrade, keep features
Testing Business Logic:
Approach:
1. Understand the application
- What does it do?
- What are the workflows?
- What are the rules?
2. Question assumptions
- Can I skip steps?
- Can I go backwards?
- Can I do things out of order?
- What if values are negative?
- What if values are very large?
3. Test edge cases
- Boundary values
- Empty values
- Unexpected types
- Concurrent requests
4. Abuse features
- Referral systems
- Loyalty programs
- Free trials
- Promotional offers
Race Condition Testing:
# Race conditions in web apps
# Scenario: Limited coupon (100 uses)
# Attack: Send 100 concurrent requests
# Burp Turbo Intruder:
def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=50,
requestsPerConnection=1,
pipeline=False)
for i in range(100):
engine.queue(target.req)
def handleResponse(req, interesting):
if '200' in req.response:
table.add(req)
# Or use Burp Repeater:
# Send to group, "Send group in parallel"
# What to test:
- Coupon redemption
- Money transfers
- Vote/like systems
- Limited inventory purchases
- Account balance operations
Key insight: Business logic testing requires thinking about what the application should do and finding ways to abuse it.
5) Automated IDOR Testing
Scaling access control testing:
Autorize Extension:
# Burp Autorize - automated authorization testing
Setup:
1. Install Autorize from BApp Store
2. Configure two sessions:
- High-privilege (admin) cookies
- Low-privilege (user) cookies
3. Browse as high-privilege user
4. Autorize replays requests with low-privilege session
5. Compares responses
Results:
🔴 Red = Access control bypassed (same response)
🟡 Yellow = Different response (investigate)
🟢 Green = Properly blocked
# Autorize catches:
- IDOR automatically
- Privilege escalation
- Missing authorization checks
Auth Analyzer Extension:
# Another Burp extension for auth testing
Features:
- Multiple session comparison
- Automatic detection of access control issues
- Good for complex role hierarchies
Setup:
1. Define sessions (admin, user, guest)
2. Browse application
3. Review flagged requests
Manual Automation with Intruder:
# Enumerate IDOR with Intruder
1. Capture request with ID parameter
GET /api/users/123/profile
2. Mark ID as payload position:
GET /api/users/§123§/profile
3. Payload: Numbers 1-1000
Or known valid IDs
4. Attack and analyze:
- Response length differences
- Status codes
- Interesting content
# Filter results:
- Remove your own ID
- Look for 200 responses
- Compare response sizes
Testing Checklist:
Access Control Testing Checklist:
□ Horizontal Access Control (IDOR)
□ User IDs in URLs
□ Resource IDs in API calls
□ IDs in request bodies
□ IDs in cookies/headers
□ File references
□ Vertical Access Control
□ Admin URLs as regular user
□ Admin API endpoints
□ Hidden parameters (role, admin)
□ Method-based bypass (GET vs POST)
□ Context-Based
□ Skip workflow steps
□ Access after logout
□ Access during restricted times
□ Access from wrong state
□ Multi-Tenant
□ Cross-organization access
□ Tenant ID manipulation
□ Shared resource access
□ API-Specific
□ GraphQL authorization
□ Batch operations
□ Nested resource access
Key insight: Automation helps scale IDOR testing, but manual review catches what automation misses.
Real-World Context: Access Control in Practice
Access control vulnerabilities in the wild:
Bug Bounty Gold: IDOR is one of the most commonly reported and rewarded vulnerability types. Simple IDORs might earn $500-2000, while critical data exposure IDORs can earn $10,000+. The simplicity-to-impact ratio is excellent.
Real Breaches: Major data breaches have resulted from IDOR. Exposing millions of user records through a simple ID enumeration. API endpoints that never checked authorization. Admin panels accessible to any authenticated user.
Testing Challenges: Access control testing requires multiple accounts, understanding of business logic, and patience. It's hard to automate completely because valid access varies by context.
MITRE ATT&CK Mapping:
- T1078 - Valid Accounts: Using legitimate access inappropriately
- T1548 - Abuse Elevation Control: Privilege escalation
- T1530 - Data from Cloud Storage: Unauthorized data access
Key insight: IDOR is the "low-hanging fruit" that keeps giving. Applications consistently fail at authorization.
Guided Lab: IDOR and Access Control Testing
Practice access control testing on vulnerable applications.