Broken access control vulnerabilities and why scanners can’t detect them
Broken access control, the vulnerability category consistently ranking on the OWASP Top 10 Web Application Security Risks list, poses the most significant challenge for application security right now. Over-reliance on automated solutions to tackle these challenges creates a false sense of security and could have severe implications for application owners.
Access control vulnerabilities allow users to access sensitive data, and gives them the ability to perform actions beyond their intended permissions. The consequences of such vulnerabilities can lead to data disclosure, modification, and even destruction.
In this post, we will discuss why broken access control vulnerabilities are often present even after vulnerability scans and assessments, as well as the importance of manual penetration testing for effective detection and mitigation.
What is access control?
Access control can be thought of as an authorization check, ensuring that access to resources and the ability to perform actions are granted to some users (e.g., administrators), and not others (e.g., regular users). These checks are mostly performed after the authentication process, where a user’s claimed identity is verified.
In web application security, access control is closely tied to the content, intended use of functionality, and the various roles that users fall into. For example, this can include preventing a low-privileged user from performing administrative functions, preventing a user from accessing another user’s resources, or any control that grants or denies access to resources or functions based on contextual factors.
When dealing with large and complex applications containing numerous user roles and functionalities, access controls can quickly become challenging to implement correctly.
What is broken access control?
Broken access control is simply what it sounds like: access control that is not functioning as intended. This would essentially be the opposite of what we have mentioned above, with some detailed examples to follow.
Insecure direct object reference (IDOR)
Consider an application that allows regular users to view and edit their account information. Each account is assigned a user ID. When an edit request is sent, the application determines which account is to be updated based on the ID included in the request. In this scenario, an attacker could manipulate an outgoing request intended to update their account, by modifying the user ID to that of a victim.
Without an access control in place, the victim’s account would receive the edit – an IDOR vulnerability with a direct integrity impact. From this point, the situation can escalate quickly. Let’s say that the attacker changes the victim’s email address and follows that up with a password reset request. This would allow them to set a new password, and ultimately take over the victim’s account.
Now that we have gained access to another user’s account, we might as well clarify two additional terms often arising on the topic of broken access control: horizontal privilege escalation and vertical privilege escalation.
Horizontal privilege escalation
Horizontal privilege escalation involves gaining access to another account’s resources with similar permissions. In the example from the previous section, if the victim account had similar permissions as the attacking user (i.e., a regular user), it would also be known as a horizontal privilege escalation. In short, apart from gaining access to another account’s resources, the attacker does not gain any additional permissions.
Vertical privilege escalation
Vertical privilege escalation involves gaining access to another account’s resources with more permissions. In the example from the previous section, if the victim account had higher permissions (e.g., moderator or administrator), then this would be known as a vertical privilege escalation. The attacker can abuse the additional permissions to stage further attacks against the application.
Path/directory traversal
Consider an application that allows users to view their invoices with the help of a built-in previewer functionality. The invoices are stored on the same server as the application is hosted, at the following absolute path:
/var/www/html/vulnerable-application/invoices/
When a user clicks on one of the invoices shown under their profile, the following request gets sent:
The previewer works by appending the value of the “file” parameter to the given absolute path. It will then retrieve the contents of that file, and then return it to the requesting user.
/var/www/html/vulnerable-application/invoices/invoice-2024-12-24.pdf
However, like the IDOR scenario, an attacker could also here capture the outgoing request, and modify its “file” parameter to a file not intended to be retrieved.
Without an access control in place, the previewer would now attempt to retrieve:
/var/www/html/vulnerable-application/invoices/../../../../../etc/hosts
The dot-dot-slash (../) sequence steps back one directory in the path (traverses to the parent directory). We have five of these sequences, meaning that we would end up at the root path of the file system (/). From this point, we enter the etc directory from where we request the hosts file.
Now, the hosts file, a default file mapping hostnames to IP addresses, will most likely not be an attacker’s first choice. We’re just using it here to showcase the possibility of retrieving files outside of the application’s directory, also known as local file inclusion. An attacker would instead attempt to retrieve sensitive files, both inside and outside of the application’s directory.
Can’t escalate? De-escalate!
As a final example, I will walk through a real-world example from a recent customer assessment. The application featured multiple user roles, all seemingly well set-up and properly separated. All attempts to elevate a regular user’s privileges, gain access to unintended resources, and perform privileged actions were prevented, thanks to numerous access controls being in place.
However, after a thorough mapping of the various user roles, we noted one discrepancy. For context, certain roles could edit and delete other users’ accounts but could only do so for accounts with lower privileges than theirs. Users with these permissions could also not perform these actions against their own account. What got overlooked was the possibility to assign any high-privileged users a lower privileged role, effectively erasing all privileges and downgrading their accounts. These downgraded accounts would now fulfill the condition to be edited and deleted by the, technically, lower-privileged account.
As the challenge of correctly implementing access controls increases with the complexity of the application, the same is true for identifying access control issues. For detection of these controls, manual security testing is the best approach as it entails a deeper understanding of the context and intended use of the application.
The limitations of vulnerability scanning
Vulnerability scanners are a popular solution for identifying flaws in applications. However, relying on them alone creates a false sense of security for application owners. While these scanners can deliver results continuously and quickly, they are limited in their ability to detect novel attack vectors or other vulnerabilities requiring intuition and reasoning.
To further drive this point, let’s liken access control vulnerabilities to another common vulnerability with similar complexities and the need for human reasoning: business logic vulnerabilities.
Business logic flaws occur when an application’s design, implementation, or internal processes deviate from its expected use. Some distinct and common examples include ordering a negative quantity of a product or redeeming the same discount code multiple times.
Even in these straightforward examples, the limitations of a vulnerability scanner become apparent. A scanner wouldn’t be able to discern the application’s intended behavior. From its point of view, a negative number is still a number, and repeated use of a certain functionality isn’t necessarily bad. Unlike other vulnerabilities such as cross-site scripting (XSS) and SQL injection, a scanner cannot simply supply an input here and look for a predefined pattern in the application’s response to determine whether something may be vulnerable.
From an offensive security standpoint, catching vulnerabilities from either the broken access control or business logic category requires the same mindset and contextual understanding of the application. In many cases, there is quite a bit of overlap as well. For instance, when assessing a file upload functionality, one test case would be to upload an unexpected file type, such as an SVG file containing a JavaScript payload, when only image files are permitted. While SVG satisfies the broad image criteria, its contained JavaScript is not intended to be parsed by a victim’s browser. If this happens to be the case, are we leaning towards a business logic vulnerability, or a circumvention of access controls?
Now, suppose a file upload functionality that is properly preventing all unintended files. A suitable test case here would be to upload a permitted file to an unintended location, such as a directory, to which the uploading user does not have write permissions. Would this scenario point towards the circumvention of access controls, or a flaw in the application’s business logic? Both can be argued.
In these cases, an understanding of the intended purpose of the file upload functionality is essential to determine whether we are violating any business rules or access controls.
In a real-world scenario, additional complexity in the form of rights, roles, external integrations, third-party libraries, dependencies, and so on, would also be added.
This context-specific complexity, twisting and turning which user should have access to which object, what data is on the verge of disclosure, when race conditions can be exploited, where social engineering possibilities are probable, etc., will be almost impossible for a vulnerability scanner to determine.
Mitigating access control vulnerabilities with pen testing
To detect and mitigate access control vulnerabilities, and other logical flaws, application owners must supplement automated scanning solutions with manual penetration testing and human reasoning. Outpost24’s SWAT is a pen testing as a service (PTaaS) solution that helps application owners achieve a deeper level of security and risk detection. SWAT offers extensive, custom, and ongoing manual testing, with the option to automate scans for continuous monitoring. Unlike traditional pen testing delivery, Outpost24’s findings are provided in real-time via a dedicated portal that also connects you directly with our security experts. The service also eliminates the concern for false positives as all findings are peer reviewed by a senior pen tester.