Broken Access Control Testing: How to Find OWASP A01 Vulnerabilities

Broken access control has been the number one web application vulnerability in OWASP's Top 10 since 2021. It dethroned injection after two decades at the top. That ranking reflects something real: it's extremely common, often subtle, and the kind of flaw that causes the highest-profile data breaches.

Unlike SQL injection or XSS, broken access control doesn't show up as a syntax error or a script tag in a response. It shows up as "I can see your data," "I can take your actions," or "I accessed a page I wasn't supposed to reach." That makes it harder to test automatically and much more dependent on understanding the application's intended authorization model.

This guide covers how to test for broken access control systematically — what to look for, how to probe it manually, what automated tools catch, and what they reliably miss.

What Broken Access Control Actually Covers

OWASP A01 is a broad category. It includes several distinct patterns that behave differently and require different testing approaches:

Insecure Direct Object Reference (IDOR) A user can access another user's resource by modifying an identifier in the request — changing ?user_id=123 to ?user_id=124 to access another account's data. The most common form and the easiest to miss with automated tools if they can't reason about data ownership.
Horizontal privilege escalation Accessing resources belonging to another user at the same privilege level. Closely related to IDOR but the pattern extends beyond direct object references — it includes taking actions (deleting, modifying) that should only affect your own resources.
Vertical privilege escalation A lower-privilege user accesses functionality or data restricted to higher-privilege roles — a standard user accessing admin endpoints, a read-only user invoking write operations, a free-tier user accessing premium features.
Missing function-level access control API endpoints and admin functions that are not linked from the UI but are accessible if you know the URL. Developers sometimes assume that hidden = protected. It isn't. These endpoints often have weaker authorization because "no one should know they exist."
Path traversal and directory access Accessing files or directories outside the intended scope by manipulating path segments — ../../../etc/passwd style attacks, or relative path manipulation in file download endpoints.
JWT and token manipulation Modifying claims in JSON Web Tokens to escalate privilege — changing a role: "user" claim to role: "admin", or altering a sub claim to access another user's data. Often combined with algorithm confusion attacks (alg: "none" or RS256 → HS256 downgrade).

Testing Methodology

Step 1: Map the authorization model

Before you test anything, understand what access control is supposed to do. For each user role in the application, document:

This map becomes your oracle for what should and shouldn't be accessible. Testing without it means you're guessing, not verifying.

Step 2: Create test accounts at each privilege level

You need at least:

If the application has organizations or tenants, create accounts in at least two separate tenants.

Step 3: Capture the authenticated request flow

Use a proxy (Burp Suite, OWASP ZAP, or any intercepting proxy) to capture authenticated requests from Account A. For each request that involves a resource identifier — user_id, document_id, order_id, account_id — note the identifier value.

Then replay those requests with Account B's session token, substituting Account A's resource identifiers. If Account B can read, modify, or delete Account A's data: IDOR confirmed.

Step 4: Test vertical escalation on every privilege-sensitive endpoint

For each endpoint that should be admin-only, replay the request using a standard user's session. For each endpoint that requires authentication, replay without authentication. Watch for:

Step 5: Enumerate hidden endpoints

Developers often build admin panels, export endpoints, and internal APIs that are never linked from the UI. Common patterns to probe:

/admin/
/admin/users
/admin/settings
/api/admin/
/api/v1/admin/
/internal/
/management/
/debug/
/console/

Use wordlists (SecLists Discovery/Web-Content/api/api-endpoints.txt and Discovery/Web-Content/common.txt) with a fuzzer against the authenticated session. A 200 or 403 (rather than 404) signals the endpoint exists.

Step 6: Test parameter manipulation

Beyond direct object references, look for:

JWT-Specific Testing

If the application uses JSON Web Tokens for authentication or authorization, these deserve dedicated attention.

Algorithm confusion (alg: none)

Some JWT libraries accept tokens with alg: "none" — no signature required. Decode your JWT, modify the payload (role: "admin"), set alg: "none", and remove the signature. If the server accepts it, the application is vulnerable.

# Decode the token (base64 each section)
echo "eyJhbGciOiJIUzI1NiJ9" | base64 -d
# {"alg":"HS256"}

# Craft a new header with alg: none
echo -n '{"alg":"none"}' | base64 | tr -d '='
# eyJhbGciOiJub25lIn0

# Build the token: header.payload. (no signature)
# Submit as: Authorization: Bearer eyJhbGciOiJub25lIn0.{modified_payload}.

RS256 to HS256 confusion

When a server uses RS256 (asymmetric), the public key is often available. Some libraries, when switched to HS256, will verify the signature using the public key as the HMAC secret. Forge a token signed with HS256 using the server's public key as the secret.

Claim manipulation

If the JWT is signed but not encrypted, you can read the claims. Check what claims are present and whether modifying them (after forging a new signature) changes authorization behavior. Common high-value claims: role, sub, user_id, org_id, tenant_id, permissions.

What Automated Scanners Catch (and What They Miss)

Access control testing is the hardest category for automated tools. Here's what to expect:

Pattern Automated detection Why
Path traversal Good Predictable payload patterns; response differences are detectable
IDOR on sequential IDs Moderate Scanner can increment IDs, but needs two accounts to compare responses
Missing function-level control Moderate Endpoint discovery works; verifying access requires understanding role model
Vertical privilege escalation Limited Requires understanding what admin vs. user should see — application-specific
IDOR on UUIDs / non-sequential IDs Poor Can't enumerate UUIDs by incrementing; requires known-good values from another account
Business logic access control Very limited Multi-step flows with contextual authorization can't be modeled by generic scanners
JWT algorithm confusion Good Well-known attack patterns; scanners can probe alg: none systematically

The honest summary: automated tools do well on the mechanical patterns (path traversal, JWT attacks, endpoint enumeration). They struggle with anything that requires reasoning about data ownership or the intended authorization model — which is exactly where the most impactful vulnerabilities hide.

IDOR in APIs vs. Traditional Web Apps

REST APIs surface IDOR more prominently because identifiers are usually explicit in URLs and request bodies rather than hidden in state. Watch for:

GraphQL deserves special attention. Object-level authorization is harder to enforce uniformly across a graph, and developers sometimes apply authorization at the resolver level rather than at the field level. Test every node and field type that returns user-scoped data.

Multi-Tenancy Testing

SaaS applications with multi-tenant architectures have an additional access control dimension: tenant isolation. A user in Organization A should never be able to read or modify data belonging to Organization B.

Test this systematically:

  1. Create accounts in two separate tenants
  2. Create resources (documents, records, configurations) in Tenant A
  3. Capture the identifiers of those resources
  4. Authenticate as a Tenant B user and attempt to access those identifiers
  5. Test both read access and write/delete access

Also test whether Tenant A's admin can access Tenant B's data. Tenant admin ≠ application admin, and this boundary is sometimes implemented inconsistently.

Access Control Testing Checklist

What Good Remediation Looks Like

Broken access control is an architectural problem as much as an implementation problem. Fixing individual IDOR findings without addressing the underlying pattern means you'll find the same class of bug in the next endpoint you add.

The durable fix is a centralized authorization layer:

For JWT-specific fixes: always verify the algorithm explicitly (never accept alg: none), use RS256 with proper key rotation, and keep sensitive authorization data server-side rather than embedding it in tokens that clients can manipulate.

Ironimo tests for broken access control patterns across your entire application — path traversal, JWT algorithm confusion, endpoint enumeration, and IDOR on sequential identifiers — using the same Kali Linux toolset professional pentesters run against production applications.

Schedule on-demand or recurring scans. Results include the exact request that reproduced the finding, the response that confirms it, and a remediation path.

Start free scan
← Back to blog