Broken Access Control Hunting Guide: How to Find Authorization Flaws That Pay Top Bounties

Key Takeaways

  • Broken access control is OWASP #1 — the most common vulnerability class in production applications, and scanners cannot reliably detect it
  • Every endpoint that takes a user identifier (ID, UUID, email, username) is a potential IDOR target — test horizontal and vertical access on all of them
  • The Autorize Burp extension automates the tedious part: replaying every request with a lower-privileged session to find enforcement gaps
  • Forced browsing, parameter manipulation, HTTP method switching, and path traversal in URL structures are the four core techniques
  • Multi-step workflows (checkout, account settings, admin panels) are where access control is most likely to break — developers enforce on the first step but forget subsequent ones

Why Broken Access Control Dominates Bug Bounty Payouts

Broken access control has been the #1 vulnerability category in the OWASP Top 10 since 2021, and it's not close. Over 94% of applications tested have some form of access control failure. The reason it persists: authorization logic is application-specific, so there's no generic scanner rule that catches it. Every access control check is custom code, and developers miss enforcement points constantly.

For bug bounty hunters, this is the highest-value hunting ground. Authorization flaws almost always have direct business impact — accessing other users' data, performing admin actions, or bypassing payment flows. Programs pay top dollar because these bugs are hard to find with automation and easy to exploit.

Understanding Access Control Models

Before hunting, you need to understand what you're testing against. Applications implement access control in three layers:

Vertical Access Control

Restricts functions by role. A regular user shouldn't access admin endpoints. A viewer shouldn't be able to edit. When vertical access control breaks, you get privilege escalation — a regular user performing admin actions.

Horizontal Access Control

Restricts data by ownership. User A shouldn't access User B's records. When horizontal access control breaks, you get IDOR — accessing or modifying another user's data by changing an identifier in the request.

Context-Dependent Access Control

Restricts actions based on application state. You shouldn't be able to modify an order after it's been shipped. You shouldn't be able to apply a discount code twice. When context-dependent access control breaks, you get business logic flaws — often the highest-paying bugs.

Setting Up Your Testing Environment

Effective access control testing requires multiple accounts. Create at minimum:

Burp Suite + Autorize Setup

Install the Autorize extension from the BApp Store. Configure it with your low-privilege user's session cookie. As you browse the application with your admin or regular account, Autorize automatically replays every request with the low-privilege session and flags responses that return the same data — indicating missing access control.

# Autorize configuration steps:
# 1. Log in as low-privilege user, copy the session cookie
# 2. In Autorize tab → Configuration → paste the cookie header
# 3. Set "Authorization Enforcement Status" filters
# 4. Browse the app as admin — Autorize tests each request automatically
# 5. Review "Bypassed!" entries — these are your findings

Core Hunting Techniques

1. IDOR — Parameter Manipulation

The most common broken access control variant. Any request containing a user-controlled identifier is a target:

# Numeric IDs — increment/decrement
GET /api/users/1337/profile → GET /api/users/1338/profile

# UUIDs — harvest from other endpoints, public profiles, or API responses
GET /api/documents/550e8400-e29b-41d4-a716-446655440000

# Email-based lookups
GET /api/account?email=victim@example.com

# Encoded IDs — decode, modify, re-encode
GET /api/order/base64({"id":42,"user":7}) → base64({"id":42,"user":8})

Don't just test GET requests. POST, PUT, PATCH, and DELETE operations with modified IDs often have weaker enforcement because developers assume "if they can view it, they can edit it" — but the view endpoint might be the only one with proper checks.

2. Forced Browsing

Access pages or API endpoints directly without navigating through the intended flow:

# Admin panels
/admin
/admin/dashboard
/internal/users
/api/admin/settings
/management/console

# Debug/diagnostic endpoints
/debug
/actuator (Spring Boot)
/elmah.axd (.NET)
/_debug_toolbar (Django)

# API versioning bypasses
/api/v1/admin/users (blocked)
/api/v2/admin/users (might not have same restrictions)
/api/internal/admin/users

3. HTTP Method Switching

Access control might be enforced for one HTTP method but not others:

# Original request (blocked)
DELETE /api/users/42 → 403 Forbidden

# Try different methods
POST /api/users/42 with {"_method": "DELETE"}
GET /api/users/42?_method=DELETE
PATCH /api/users/42 with {"active": false}

# Method override headers
X-HTTP-Method-Override: DELETE
X-Method-Override: DELETE
X-HTTP-Method: DELETE

4. Path Traversal in URL Structures

Bypass path-based access control with URL manipulation:

# Direct path (blocked)
GET /admin/users → 403

# Path traversal bypasses
GET /admin/./users
GET /./admin/users
GET /admin%2fusers
GET /ADMIN/users (case sensitivity)
GET /admin/users;.css (path parameter injection)
GET /admin/users%00 (null byte — legacy systems)
GET //admin/users (double slash)

5. Multi-Step Workflow Bypass

Applications often enforce access control on step 1 of a workflow but skip checks on subsequent steps:

# Step 1: View order (access control enforced) ✓
GET /orders/42 → 403 for non-owner

# Step 2: Modify order (access control missing) ✗
PUT /orders/42/address → 200 OK (no ownership check!)

# Step 3: Cancel order (access control missing) ✗
POST /orders/42/cancel → 200 OK

Map every multi-step workflow in the application: checkout flows, account settings changes, document approval chains, invitation systems. Test each step independently with a different user's session.

6. Referer/Origin Header Manipulation

Some applications use the Referer header as an access control mechanism:

# Request blocked without proper Referer
GET /admin/users → 403

# Add Referer header
GET /admin/users
Referer: https://target.com/admin/dashboard
→ 200 OK

API-Specific Access Control Testing

Modern applications expose most functionality through APIs, and API access control is consistently weaker than UI access control:

Common Bypass Patterns

Role Parameter Injection

# Registration or profile update with role parameter
POST /api/register
{"username":"attacker","password":"pass","role":"admin"}

# Mass assignment — add fields the UI doesn't expose
PUT /api/profile
{"name":"attacker","isAdmin":true,"permissions":["admin.all"]}

JWT Claim Manipulation

# Decode JWT, modify role claim, re-sign with none algorithm
# Header: {"alg":"none","typ":"JWT"}
# Payload: {"sub":"1337","role":"admin","iat":1713200000}
# Signature: (empty)

Token Scope Escalation

# OAuth token issued for read scope used for write operations
# Token: scope=read
POST /api/users/42/delete → Check if scope is actually enforced

Writing High-Impact Reports

Access control bugs need clear impact demonstration. Structure your report:

  1. Title: Specific action + specific impact. "IDOR in /api/users/{id}/billing allows any authenticated user to view other users' payment methods"
  2. Steps to reproduce: Include exact requests with both the authorized and unauthorized sessions
  3. Impact: Quantify — how many users affected? What data exposed? Can it be automated for mass exploitation?
  4. Proof: Show the response containing another user's data. Redact PII but make the access clear

Severity mapping for access control bugs:

Automation Strategy

While access control testing is fundamentally manual, you can automate the repetitive parts:

  1. Autorize — passive testing as you browse. Catches the low-hanging fruit automatically
  2. Custom Burp macros — replay specific request sequences with different sessions
  3. Auth matrix — build a spreadsheet mapping every endpoint × every role. Systematically test each cell
  4. Nuclei templates — for forced browsing checks against known admin paths

The manual work that can't be automated: understanding the application's business logic, identifying which resources belong to which users, and recognizing when a response that "looks normal" actually contains data from the wrong user.

Checklist: Broken Access Control Testing

Advertisement