Broken object level authorization
Failing to enforce proper permissions
Select your ecosystem
What is broken object level authorization?
Broken object level authorization (BOLA) arises when an API fails to enforce proper permissions for individual objects within its endpoints. BOLA allows attackers to manipulate object identifiers (such as IDs) to access or modify resources they shouldn’t have access to. This is typically due to missing or inadequate authorization checks for specific object references at the API level.
For instance, an e-commerce API may permit an attacker to fetch or alter sensitive data, such as customers' postal addresses, by replacing an object ID in the request URL or payload for an "orders" endpoint. BOLA can lead to unauthorized access, data manipulation, and even deletion of critical resources.
In this lesson, you will learn how BOLA vulnerabilities work and how to secure your APIs against them. We will explore a real-world-inspired exploit scenario, dissect the vulnerability, and provide mitigations and secure coding practices.
Let's walk through an example of broken object level authorization.
To understand this vulnerability, let’s analyze how the server processes requests:
- The API relies solely on the
id
parameter from the client request to fetch data from the database. - No checks are performed to confirm if the requesting user has permission to access the resource.
The lack of validation leads to unauthorized access, making this a classic BOLA vulnerability.
The code snippet below is vulnerable to broken object level authorization (BOLA) because it directly uses the userId
from the request path (req.params.id
) to fetch and return reservation data without validating if the requesting user is authorized to access it. This lack of validation allows attackers to exploit the endpoint by guessing or enumerating valid userId values, potentially accessing private reservation details of other users.
The vulnerability lies in the absence of authentication and authorization checks in database.fetchReservations(userId)
. This function blindly trusts the input from the client without confirming the user's identity or permissions. To mitigate this, the application should verify that the userId in the request matches the currently authenticated user or enforce strict access control policies to ensure users can only access their own data.
What is the impact of broken object level authorization?
BOLA vulnerabilities can have devastating security implications. The criticality of any one particular BOLA vulnerability depends on the sensitivity and quantity of data that can be edited or accessed by the attacker. At worst, the exploitation of a BOLA vulnerability could result in a mass-scale data breach.
It's important to note that BOLA vulnerabilities aren't just about accessing data, it's also about editing or deleting data, so the impacts also expand to data integrity issues and service disruptions. Again, the full impact will be determined by the functionality that is being abused.
When determining impact, it's also pertinent to consider the likelihood that the vulnerability will be discovered and exploited. Because BOLA is quite a simple class of vulnerability, it is highly likely that it will be discovered and exploited when compared to more complex vulnerability classes.
How do you mitigate broken object level authorization?
Mitigating BOLA will depend on the specific nature of the application, but in general it requires using policies and server-side checks to validate user permissions for each resource. It is best if this can be achieved further up the stack - for example by using middleware or framework features to enforce authorization checks globally, rather than needing to custom-code permissions checks on every endpoint.
Another mitigating factor is the format of object IDs. If incrementing integers are used to identify objects, then they are easy to guess. Using the same example as above, if an attacker wanted to enumerate the reservations of all users they could write a basic script that pulls all details from each URL, like this:
For this reason, it's best to use object IDs that are not as predictable, such as UUIDs, that way if an attacker has no way of enumerating the UUIDs, even if no other access controls are implemented, it will be very difficult to exploit at scale. It should be noted that this is not a full mitigation for BOLA vulnerabilities, only a mitigating factor.
The updated JavaScript code snippet demonstrates how to mitigate a BOLA vulnerability by implementing robust authorization checks.
The code compares the authenticated user's ID with the requestedId obtained from the URL parameter (req.params.id
). If they don't match, rather than sending back any details, the server will respond with a 403 Forbidden status, preventing the attacker from getting any details that they shouldn't have access to.
The vulnerable version of the code simply returned the details without checking that the user ID being requested was the same as the authenticated user.
Test your knowledge!
Keep learning
Learn more about API security and BOLA from these resources:
- OWASP API Security Project: https://owasp.org/API-Security/editions/2023/en/0xa1-broken-object-level-authorization/
- Snyk’s API Security Guide: https://snyk.io/blog/owasp-top-10-api-security-vulnerabilities/