Treating the BOLA Vulnerability
For readers that may be unfamiliar with the name BOLA (Broken Object Level Authorization), it is the most severe and most common API vulnerability today according to OWASP.
This is not a newly discovered class of vulnerability, as it is the same thing as an IDOR. However, it is very common in APIs due to their stateless nature, which exposes a lot of object IDs or endpoints that handle object identifiers. The ease of exploitation, potential for high impact and inability of DAST/SAST solutions to detect makes it an important one to look out for.
At the heart of any vulnerability management process is a plan for treating vulnerabilities through detection, response and prevention. Therefore, we’ll be taking a look at the different measures available for finding, fixing and preventing BOLA.
Before going through the details on mitigation, I have included a brief overview below to enable a better understanding of the vulnerability. Feel free to skip to the next section if you understand how a typical attack scenario works.
Brief BOLA/Exploit Overview
The BOLA vulnerability usually arises when an application exposes a reference to an internal implementation object, which can then be exploited by modifying user-supplied input to obtain unauthorized access (provided proper authorization checks are not present).
Let’s assume we have a REST API for an online bookstore, and we come across an endpoint for modifying book reviews that leaks a UUID. From a security testing point of view, the API request/response would look something like the below;
// Request
PATCH /api/books/reviews HTTP/1.1
Host: bookxpo.com
Cookie: xxxxx
...
{"uuid":"7b53f909-cb2b-4fec-b3d4-4d06e82508d9","review":"Great Read","book":"4","author":"aj"}
// Response
HTTP/1.1 200 OK
Server: nginx
Set-Cookie: xxxxx
...
{"code":200,"status":"success",{"uuid":"7b53f909-cb2b-4fec-b3d4-4d06e82508d9","token":"200901", "email":"fisayoajayi@linkedin.com","review":"Great Read","book":"4","author":"aj"}}
Looking at the uuid parameter, we understand that it is a reference to a user object but we may not be able to modify the object ID if it can’t be enumerated.
The first thing that needs to be confirmed is if there is any authorization check in place e.g. by creating a different account and using it’s uuid in place of the previous one. If the review modification is successful, it means the API is vulnerable.
However, this is not enough since we also need to be able to guess uuid to prove high impact.
If we are to assume that the uuid is not enumerable, what we’ll find most times is that there always exists API endpoint(s) that can be used to get another user’s uuid. For example, a PUT request for an invalid review could be used as shown below;
// Request
PUT /api/books/0.4/reviews HTTP/1.1
...
{"account":"fisayoajayi@linkedin.com","review":"Great Read"}
// Response
...
{"code":401,"status":"failure","uuid":"7b53f909-cb2b-4fec-b3d4-4d06e82508d9","message":"Review not found"}
This now makes it possible to iterate upon different email addresses to get a list of valid uuid’s.
TREATING BOLA
Fixing
The main issue here is the lack of proper authorization check that allows access when using a different Identifier.
So what typically happens at the backend is that the route handler doesn’t include the function(controller) that performs the authorization check.
For example, the reviewsController.updateReview function shown below, which should validate if each user has permission to update reviews, may be missing.
// Route handler
...
router.patch('/api/books/reviews', auth.isAuthenticated(), reviewsController.updateReview());
...
In conclusion, the solution for fixing a BOLA vulnerability, is to perform access control checks before manipulating resources. Keep in mind that we are assuming that the actual code in the authorization mechanism is robust enough to covers all the different use cases that may be exploited.
Preventing
The above solution may work for fixing BOLA vulnerabilities discovered in code, but it isn’t an optimal solution for prevention since it requires all the developers to know where and when to implement the access control checks. It is always better to have a system in place, instead of relying on humans to make the correct decision each time.
However, there isn’t yet a system that can be easily implemented to prevent this. One advice will be to use a defense in depth approach depending on the peculiarities of your application. Examples include combining the use or implementation of ACLs, temporary IDs mapped to internal IDs, incalculable UUIDs and other solutions that may help with mitigation.
Finding/Detecting
Generally speaking, access control vulnerabilities (such as BOLA) are difficult to detect using traditional application security tools (e.g SAST/DAST). They are mostly detected through manual code audits or penetration tests.
However, certain techniques like stateful fuzzing can help but requires a lot of input or supervision to interpret results. An example of a tool that implements this is yelp’s fuzz_lightyear.
CONCLUSION
It is clear to see that the BOLA vulnerability is an interesting one for attackers but can be difficult to prevent. We have also highlighted some points which could help address some of the issues raised. If you would like to learn more about this, you can check this detailed article.