Access Control Vulnerability Testing
When to Use
Use this skill when you need to determine whether a web application correctly enforces authorization decisions for every user, role, and request type. Access controls are the mechanism by which an application decides whether a given request is permitted to perform an action or access a resource. Broken access controls affect 71% of web applications and enable attackers to take full control of administrative functionality, access other users' sensitive data, or bypass business logic constraints.
This skill applies to authorized penetration tests, security code reviews, and appsec audits. It is not a substitute for legal authorization to test a target application.
Core Concepts
Three Access Control Categories
Vertical access control enforces separation between privilege levels (ordinary user vs. administrator). Vertical privilege escalation occurs when a lower-privilege user successfully accesses higher-privilege functions.
Horizontal access control enforces that users can only access their own resources (documents, orders, accounts). Horizontal privilege escalation occurs when a user accesses another user's resources.
Context-dependent access control enforces that users access application states only in the prescribed sequence. Business logic exploitation occurs when a user bypasses required workflow steps (for example, skipping the payment stage of a checkout flow).
Horizontal and vertical escalations frequently chain: discovering another user's document identifier may allow modifying that user's security role, converting horizontal access into vertical compromise.
Six Vulnerability Categories
- Completely unprotected functionality — Sensitive functions accessible to anyone who knows the URL; the only "protection" is UI-level link omission.
- Identifier-based functions (Insecure Direct Object Reference / IDOR) — Authorization based solely on a resource identifier passed as a request parameter, with no server-side ownership check.
- Multistage function bypasses — Authorization checked only at step 1 of a multi-request workflow; later steps assume legitimacy without re-verifying privilege.
- Static file exposure — Protected content served as static files directly accessible by URL, bypassing all application-layer authorization.
- Platform misconfiguration — Access rules defined at the web server or application server layer (URL path + HTTP method) that can be bypassed by substituting an alternative HTTP method or specifying an unrecognized method.
- Insecure access control methods — Authorization decisions driven by client-controllable data: request parameters (
admin=true), HTTP Referer header, or IP-based geolocation.
Process
Phase 1: Reconnaissance and Access Control Mapping
Step 1: Understand the authorization model.
Before probing, answer these questions from application mapping output or source code:
- Does the application segregate users into distinct roles with different functionality?
- Does any functionality give individual users access to a subset of resources of the same type (documents, orders, accounts)?
- Do administrators use the same application instance as regular users?
- Are there identifiers in URLs or POST bodies that signal which resource or function is being targeted?
- Are there parameters that appear to carry privilege flags (
admin, role, isAdmin)?
WHY: Access control testing without understanding the intended authorization model produces false positives (expected differences flagged as vulnerabilities) and false negatives (violations that look like normal variance). The authorization model defines what "violation" means.
Step 2: Identify all application surfaces.
Using your proxy history and any content discovery output, catalog:
- All URLs and endpoints, noting which require authentication
- All functions that modify state (create, update, delete operations)
- All resource types with per-user ownership semantics
- All multi-step workflows (checkout, account creation, approval chains)
- All static file downloads (PDFs, spreadsheets, binaries)
- All client-side code (JavaScript, decompiled browser extension components) for hidden URLs or admin menu items
WHY: Poorly protected functionality often exists outside the normal navigation paths. JavaScript building role-conditional UI elements frequently references admin URLs that are not linked from ordinary user interfaces.
Phase 2: Multi-Account Testing Workflow
This is the primary methodology. It requires at minimum two accounts: one high-privilege and one low-privilege.
Step 1: Map the application as the high-privilege user.
With Burp configured as your proxy (interception disabled), browse all application functionality using the high-privilege account. This builds a complete site map of all accessible endpoints.
WHY: You need to know what the high-privilege account can access before you can test whether the low-privilege account is incorrectly permitted to access it. Starting with the low-privilege account means you may never discover the privileged endpoints to test.
Step 2: Use Burp's "Compare Site Maps" feature.
In Burp's Target tab, right-click the site map and select "compare site maps." Configure the second site map to re-request all items from the first site map using the low-privilege session (via a recorded login macro or a specific session cookie). Burp will highlight added, removed, and modified responses between the two maps, including a diff count for modified items.
WHY: Manual comparison of dozens or hundreds of endpoints is error-prone and slow. Automated replay eliminates the mechanical work while preserving human judgment for interpreting results — two identical responses to an admin function indicate a violation; two different responses to a personal profile page are expected and benign.
Step 3: Interpret comparison results with context.
Identical responses do not always indicate a vulnerability (a search function returning the same results is harmless). Different responses do not always indicate correct enforcement (an admin function returning different content each visit may still be accessible). Apply judgment for each flagged item.
Step 4: Test horizontal access control with two same-privilege accounts.
Identify resources owned by Account A (document IDs, order numbers, account references). From Account B's session, request those same resource identifiers directly — either by URL or by replaying the POST parameters. Access to Account A's resource from Account B's session is a horizontal privilege escalation.
WHY: The Burp site map comparison approach tests vertical access control effectively. Horizontal escalation requires explicit cross-account resource substitution because both accounts see the same set of endpoints.
Phase 3: Testing by Vulnerability Category
Category 1: Completely Unprotected Functionality
- Review all JavaScript in the application for conditional UI construction based on role flags. Extract any admin URLs referenced in conditionally-rendered code.
- Review HTML comments for references to unlisted endpoints.
- Request admin/management URLs directly from a low-privilege or unauthenticated session.
- If the application uses direct access to server-side API methods, test for additional undiscovered methods using similar naming conventions (
getBalance → getAllBalances, getCurrentUserRoles → getAllUserRoles, listInterfaces, getAllUsersInRoles).
WHY: Security through obscurity is not access control. URLs appear in browser history, server logs, proxy logs, and bookmarks. URL knowledge cannot be revoked when a user changes roles. Any function reachable by knowing its URL without a server-side authorization check is unprotected, regardless of whether the URL is published.
Category 2: Identifier-Based Functions (IDOR)
- Identify all request parameters that reference resources: document IDs, account numbers, order references, user IDs.
- Determine whether identifiers are sequential (integers), partially predictable, or cryptographically random (GUIDs).
- For sequential identifiers: substitute your own identifier with adjacent values or values observed in application logs and error messages.
- For non-sequential identifiers: test the ones you already possess from your own account activity. Even non-guessable identifiers expose a vulnerability if the server fails to verify ownership.
- If you can generate multiple identifiers rapidly (by creating documents or orders), analyze the sequence for predictability patterns using session token analysis techniques.
- If access controls are confirmed broken and identifiers are predictable, document the automated harvest risk.
WHY: Resource identifiers are not secrets. They appear in server logs, are transmitted via clients, and may be observed from within the application itself (logs, audit trails). The server must verify that the requesting user is authorized to access the specific resource identified, regardless of how the identifier was obtained.
Category 3: Multistage Function Bypasses
- Walk through the complete protected workflow as the high-privilege user, noting every HTTP request in sequence (including redirects, form submissions, and parameterless confirmation requests).
- Re-execute each individual request in the sequence from a low-privilege session. Do not assume that step 3 is protected because step 1 is protected — test each step independently.
- Use Burp's "request in browser in current browser session" feature to replay each high-privilege request within a low-privilege browser session. Paste the Burp-provided URL into the low-privilege browser and observe whether the action succeeds.
- Identify any stage where the application passes data validated at an earlier step as a client-side parameter to a later step (hidden fields, query string values). Test whether modifying those parameters at the final stage allows bypassing the earlier validation.
WHY: Developers commonly validate authorization at the entry point of a workflow and assume that any user who reaches later stages must have passed the earlier checks. This assumption is violated whenever an attacker can directly submit a request to a later-stage endpoint. Each step must independently verify that the current session is authorized to perform the action, not just that it reached this step via a valid earlier step.
Category 4: Static File Exposure
- Complete the legitimate process for accessing a protected static resource (purchase, login, privilege grant) and capture the final download URL.
- Using a different session (low-privilege or unauthenticated), request that URL directly.
- If direct access succeeds, analyze the URL naming scheme for the full resource set. Sequential or patterned names (ISBNs, sequential IDs) allow bulk enumeration.
WHY: Static files served directly from the web root bypass all application-layer code. No server-side script runs to verify the requester's authorization. The only protection available is web-server-level authentication or serving files indirectly through a dynamic page that implements authorization logic.
Category 5: Platform Misconfiguration (HTTP Method Bypass)
- Using the high-privilege account, identify sensitive state-changing requests (create user, change role, delete record).
- If the request does not include anti-Cross-Site Request Forgery tokens or similar protections, attempt to re-issue it using alternative HTTP methods: substitute
POST with GET, then HEAD, then an arbitrary invalid method (e.g., JEFF).
- If the application honors any alternative method and performs the action, test that method's access controls using a low-privilege account.
WHY: Platform-level access rules (web server or application server configuration) often deny specific HTTP methods but allow others. HEAD requests are typically handled by the same code as GET, so if GET performs a sensitive action, HEAD may too. Some platforms route unrecognized HTTP methods to the GET handler, allowing arbitrary method names to bypass deny rules that only enumerate specific blocked methods.
Category 6: Insecure Access Control Methods
Parameter-based access control:
- As a high-privilege user, observe whether any requests contain parameters indicating privilege level (
admin=true, role=admin, isManager=1).
- As a low-privilege user, add or modify these parameters to claim elevated privilege.
- Where application pages show different functionality to different roles, try appending privilege parameters to the URL query string and POST body.
Referer-based access control:
- Identify functions you are legitimately authorized to access.
- Remove or modify the
Referer header on those requests. If access fails, the application is using Referer as an authorization signal.
- For functions you are not authorized to access, forge a
Referer value matching the administrative page that would legitimately precede the request.
Location-based access control:
- If the application enforces geographic restrictions, test bypass via a web proxy, VPN, or data-roaming mobile device in the permitted location.
- Test direct manipulation of any client-side geolocation mechanisms.
WHY: Any access control decision based on data the client can control is fundamentally insecure. Request parameters, Referer headers, and IP geolocation are all attacker-controllable. Authorization decisions must be driven exclusively from server-side session state, which the attacker cannot forge.
Phase 4: Testing with Limited Account Access
When only one account is available:
- Use content discovery techniques to enumerate functionality not linked from the normal interface. Low-privilege browsing is often sufficient to both enumerate and directly access unlisted administrative functionality.
- Review all client-side HTML and scripts for references to hidden functionality or script-driven UI elements.
- Decompile any browser extension components to discover references to server-side endpoints.
- Test for
Referer-based access control as described above.
- Probe for parameter-based privilege escalation by appending common privilege parameters to requests.
Phase 5: Documentation
For each confirmed finding, record:
- Vulnerability category (from the six-category taxonomy above)
- CWE identifier (CWE-862 for missing authorization, CWE-639 for IDOR, CWE-863 for incorrect authorization, CWE-284 for general broken access control)
- Affected endpoint(s) with full request detail
- Proof of exploitation: what was accessed or performed, from which account, with what evidence (response body, diff count, HTTP status)
- Privilege escalation type: vertical, horizontal, or business logic
- Severity: consider data sensitivity, actions permitted, and chainability to further compromise
- Countermeasure (see Securing Access Controls section)
Securing Access Controls
Use these principles when documenting remediation recommendations or reviewing defensive implementations:
Avoid the common pitfalls:
- Do not rely on URL or resource identifier secrecy as a substitute for authorization. Assume every URL and identifier is known to every user.
- Do not trust client-submitted parameters to indicate privilege (
admin=true). All access control decisions must derive from server-side session state.
- Do not assume that because a user cannot reach page B from page A, they cannot request page B directly.
- Do not transmit validated data via the client between workflow stages without revalidating it on receipt at each stage.
Implement a centralized authorization model:
- Document access control requirements for every unit of functionality: who can use it and what resources they can access via it.
- Implement a single central application component responsible for all access control decisions.
- Route every request through this component before any functional code executes.
- Use programmatic enforcement (every page must call the central component) to prevent omissions — make it impossible to ship a page that lacks an authorization check.
Apply a multilayered privilege model (defense in depth):
- Application layer: session-driven authorization via a central component.
- Application server layer: URL-path and HTTP-method rules using a default-deny model (deny anything not explicitly permitted).
- Database layer: separate database accounts per user role with least-privilege grants; read-only accounts for read-only operations.
- Operating system layer: application components run under least-privilege OS accounts.
Protect static content by either: (a) serving files through a dynamic handler that performs authorization before streaming the file, or (b) using HTTP authentication or application-server access controls to wrap direct file requests.
For high-sensitivity functions (bill payee creation, privilege changes): implement per-transaction reauthentication or dual authorization to mitigate both access control bypass and session hijacking impact.
Log all access to sensitive data and all sensitive actions to enable detection and investigation of access control breaches.
Examples
Example 1: Vertical Privilege Escalation via Unprotected Admin URL
Scenario: E-commerce platform with separate admin and customer roles. Penetration test with one admin account and one customer account.
Trigger: Burp site map comparison shows admin account visited /admin/users/list and /admin/users/new. Low-privilege replay returns HTTP 200 for both with the same response body as the admin.
Process:
- Browsed application as admin; site map captured all admin endpoints.
- Configured Burp to re-request the site map using the customer session cookie.
- Compared site maps:
/admin/users/list showed diff count 0 (identical responses).
- Confirmed: customer session receives the full user list including credential data.
- Tested
/admin/users/new POST with customer session — new admin account created successfully.
Output: Critical finding — CWE-862 (Missing Authorization). Completely unprotected admin functionality. Recommended: central authorization component checks session role before any admin handler executes.
Example 2: Horizontal Privilege Escalation via IDOR
Scenario: Document management application. User A and User B both have standard accounts. Authorized test with both accounts.
Trigger: After logging in as User A, the document list shows URLs in the form /ViewDocument.php?docid=1280149120. Login as User B and browse to User B's own document at docid=1280149125.
Process:
- While authenticated as User B, modified
docid parameter to 1280149120 (User A's document ID).
- Application returned User A's document in full without any authorization error.
- Sequentially tested adjacent document IDs; all returned documents belonging to other users.
- Confirmed identifiers are sequential integers — enumerable with Burp Intruder.
Output: High finding — CWE-639 (Authorization Bypass Through User-Controlled Key). Server does not verify that the requesting session owns the referenced document. Recommended: on every document request, verify that the authenticated user's ID matches the document's owner field before returning content.
Example 3: Multistage Bypass and HTTP Method Substitution
Scenario: SaaS application with an "Add User" admin workflow (3 steps: choose role, enter details, confirm). Single admin account available; one regular-user account.
Trigger: Application mapping reveals the workflow spans three POST requests: /admin/newuser/step1, /admin/newuser/step2, /admin/newuser/step3. Step 1 returns 403 for the regular-user session. Steps 2 and 3 have not been tested independently.
Process:
- As admin, walked through the complete workflow; captured all three POST requests in Burp.
- Using Burp "request in browser in current browser session," replayed step 2 and step 3 requests inside the regular-user browser session.
- Step 2 returned the details form with HTTP 200. Step 3 accepted the submission and confirmed user creation.
- Confirmed that only step 1 checks authorization; steps 2 and 3 assume legitimacy.
- Additionally tested step 3 with HTTP method changed from POST to HEAD — server executed the creation action (inferred from subsequent user list check) while returning no response body.
Output: Critical finding — CWE-285 (Improper Authorization) on steps 2 and 3; CWE-284 on HTTP method bypass. Recommended: each step independently verifies the session role; platform rules use default-deny for all HTTP methods except those explicitly permitted for each endpoint.
License
This skill is licensed under CC-BY-SA-4.0.
Source: BookForge — The Web Application Hacker's Handbook: Finding and Exploiting Security Flaws by Dafydd Stuttard, Marcus Pinto.
Related BookForge Skills
This skill is standalone. Browse more BookForge skills: bookforge-skills