Finding Broken Access Controls
This blog post is intended to be a guide on effective and efficient methods of identifying broken access control. This is not an end-all-be-all guide and explanation of broken access controls.
What Are Access Controls?
Access controls are policies put in place to prevent unauthorized access. They delegate which users or roles should have access to a resource or action. The simplest form of an access control policy requires a user to authenticate to access a page. This might be enough for some basic applications, but many applications have multiple registered users, requiring additional policies to handle various access levels.
Developers can implement access controls in multiple ways, including Role-Based Access Control (RBAC), which grants access based on an individual's roles and responsibilities within the organization or user base. Some examples of roles include admin, user, sales, superuser, management, and customer. When not implemented correctly, the results can lead to different types of issues.
Types of Issues
Broken access controls can be placed into three broad categories. Lateral, horizontal, and context-dependent issues.
Lateral access control issues happen when a user can access or elevate their privileges to view or modify data they shouldn't have access to. This can be a result of lacking access checks or weak implementation of access checks, such as by checking user defined data, for example query parameters like role=user
or isAdmin=false
. When these parameters are passed through the URL, cookies, or anywhere else in the HTTP request, they can be easily modified.
Horizontal access controls issues occur when a user can access another user's data. For example, one customer having access to another customer profile or payment information. An example would be an application that uses a URL such as https://example.com/Profile?user=123
or https://example.com/viewOrder?order=003932
. Applications that use a numerical value to access a resource are more prone to this kind of attack than an application using randomly-generated user IDs (guid).
Context-dependent access controls prevent users from doing actions out of order, such as correctly completing the payment in a checkout process before placing the order or verifying their password before accessing sensitive data. For example, an access control policy that uses the Referer
header, such as https://example.com/payment
to verify the user completed the payment process, can be bypassed by modifying the header. Parameters like paymentComplete=true
or passwordVerified=true
are susceptible to context-dependent access control issues.
Tools like Burp Suite Pro and Firefox Multi-Account Containers can help speed up the process of identifying access control issues and reduce the headache of managing multiple accounts.
Configuring Auth Analyzer and Autorize
Firefox multi-container helps manage testing with multiple accounts. The alternative to using this extension is opening a browser instance for each test account. Even with two or three accounts, it's easy to get confused and flustered with multiple browser windows. Firefox multi-container allows tabs to act independently of each other, similar to having multiple browser instances open, separating session states.
A container should be created for each test account. In this example, three containers are created. An admin, read-only, and parts update account.
To set up Auth Analyzer, grab the session cookies from the proxy history and create the appropriate sessions in auth analyzer. Paste the session cookie(s) for each user's session. Notice that an admin session doesn't need to be created because it's the account we'll use to browse the site.
Start browsing the application, and Auth Analyzer will repeat the request for each session and flag potential auth bypass issues. Note that filters can be applied to repeat only in-scope traffic.
Setting up Autorize is simple and similar to Auth Analyzer. Grab the session cookies for the second account and paste them into the headers field. Additionally, the "Intercept request from Repeater" can be checked to forward Repeater traffic to Autorize.
Add an interception filter to make sure only in scope items are passed to Autorize.
Both extensions can be customized for additional actions such as matching and replacing text and configuring how issues are detected. It's important to note, the two extensions are not identical and features/limitations should be taken into consideration when using them.
Identifying Horizontal Access Control Issues
After or during the reconnaissance phase, identify any numerical or guessable parameter values such as user=123
, account=user
, or any values set to false isAdmin:false
.
While browsing our test application, the "pr" parameter is marked by Auth Analyzer as "BYPASSED". Numerical values jump out as candidates for broken access controls because of how easy it is to guess another resource's ID. Let's send this request to Intruder and see if we can access any pre requisition details that we should not have access to.
Select the payload type "Numbers" and set the start and end range. Adjust and increase the range/steps as needed.
Reviewing the results, we can identify a valid value by the content length. In this example invalid responses have a length of 7623, anything greater contains valid data. Viewing the responses confirms we can access other customers data.
Auth Analyzers compare feature can also be used to find these issues. Instead of using Intruder to spray values at the parameter, we can use two accounts to check if accountA can access accountB data. Add the necessary headers for account B in the configuration tab and start browsing the application with account A.
Using the "compare view" feature, we can view the results using the render tab to confirm customer B can access customer A records by comparing the original response, customer A, to the "read_only" response, customer B.
Autorize can be used to accomplish the same as above. Autorize will return the original and modified response of repeated traffic.
When using two or more accounts, Autorize or Auth Analyzer is faster than using Intruder for identifying insecure direct object references (IDOR) issues. However, it isn't effective for identifying all issues related to parameter/cookie values, referer headers, platform or location-based controls. Follow up with Intruder and manual inspection as needed.
Lastly, any boolean values identified should be swapped to test if access controls or permissions are affected. While you can do this manually by intercepting and modifying the request, we can automate this process using Burp Suites match and replace rules.
Identifying Lateral Access Control Issues
Browsing with an admin account, we can see that admin users have access to the "Admin" panel. Instead of manually copying the link for each admin menu and attempting to view it with our other two users, we can use Auth Analyzer or Autorize to automatically repeat the request for us.
This application is a great example of how automated tools can fail and provide false negatives. To reduce the amount of false negatives, automated testing should always be followed up by manual inspection. While browsing through the admin section, we can see that Auth Analyzer has started repeating the request for us and reporting access controls are not being bypassed.
But when inspecting the responses we can see, access controls are not being enforced on the "CustomerList" menu.
Autorize can be customized to modify how bypass issues are detected. Let's configure Autorize to prevent false negatives. We know from previous requests that the error message "Not Authorized" is received and a content length of 6810 is returned when access controls are enforced.
In the "Enforcement Detector" tab, we add two filters and apply the "Or" rule instead of "And" to instruct Autorize that any response that matches either of these two rules is enforcing access controls. One filter is to detect any mention of "Not Authorized" and another to catch any response with a content length of 6810.
Repeating the process, we see that Autorize is reporting a potential issue with the customerlist.aspx request which is better than the false negatives provided by Auth Analyzer. At the time of writing this post, Auth Analyzer doesn't support customization of the way issues are detected.
The process with Auth Analyzer and Autorize should be repeated on all functions of the application, not just menus. For example, if the GET request for the "UpdateUser" page enforces access controls, update a value and see if the following POST request is properly applying the access controls.
Identifying Context Dependent Access Control Issues
For this example we'll use the "Multi-step process with no access control on one step" Lab provided by Portswigger.
An admin and two non-admin account are provided. Browsing the application as "administrator" we see the application has an admin panel with the option to upgrade and downgrade a users role.
Clicking "Upgrade User" requires the administrator to confirm the action before committing the change.
After Clicking "Yes" the POST request is submitted and revisiting the admin panel confirms carlos is now an ADMIN.
Using Burp Suite we identify two POST request are sent in the process. The initial request and the one sent after confirming the action. The difference between the two is the parameter confirmed=true
.
Let's send the second POST request to repeater and attempt upgrading privileges from the second non-admin user wiener. Logging in to the account we can see the Admin panel is missing in weiners menu.
Using the saved request in Repeater, we can swap out the original administrator cookies for our current session cookies as wiener and change the username value to "wiener" and submit the request.
Refreshing the page we can see weiner has self-granted admin access.
When assessing an application, having admin access is important to ensure all application features are enumerated and tested. In this lab, if only non-admin accounts were provided, it's possible this privilege escalation path would have been missed.
Thoughts on Auth Analyzer vs Autorize
They both have their pros and cons. Autorize has the benefit of customizing how bypass issues are detected and automatically submitting unauthenticated requests. Autorize is efficient and great for applications where only one or two users are provided/available.
When multiple accounts are provided, Auth Analyzer has a clear advantage with support for multiple sessions. While it doesn't support customizing how bypass issues are detected, Auth Analyzer provides several ways to customize how headers, cookies, and parameters are handled.
Like all tools, it comes down using the right tool for the right situation and personal preference.
Final Words
These are just a few examples and methods of identifying broken access control. There are several other access controls issues not mentioned in this blog post and as Offensive Security professionals, it's our job to analyze the situation and adapt our testing methodology.
References
OWASP Cheat Sheet - https://cheatsheetseries.owasp.org/cheatsheets/Access_Control_Cheat_Sheet.html#access-control-policy
Burp Suite Autorize - https://portswigger.net/bappstore/f9bbac8c4acf4aefa4d7dc92a991af2f
Burp Suite Auth Analyzer - https://portswigger.net/bappstore/7db49799266c4f85866f54d9eab82c89
Access Control Vulnerabilities and Privilege Escalation - https://portswigger.net/web-security/access-control
All recommendations and case studies presented by Tevora are for information purposes only and not intended to be for the purposes of providing information security advice. Any use of this information for other means is prohibited.