OWASP API Top 10: Broken Object Level Authorisation

(Note: If you'd like more on the OWASP API Top 10 then take a look at my Pluralsight course on OWASP Top 10: API Security Playbook)

This is the first entry in the OWASP API top 10 (API1:2019).

Some aspects of software development can be easy to get wrong and authorisation is one of them. This is reflected in the fact that there are two vulnerabilities in the OWASP API top 10 relating to it (Broken Function Level Authorisation being the other).

What is it?

When we talk about object level authorisation, we're looking at who can access what data. The objects might be any number of things a user can access. For example, in an online shop, those objects could be the contents of your basket, past orders, current address, credit cards etc.

As a logged in user you would expect that only you can access your own objects, but if there's a problem with authorisation then other users might be able to access them too.

What Does an Attack Look Like?

Before we go into detail, we need to make sure we understand what a typical request for those objects might look like. The ID we use to get that object might appear in a number of places in a request, if we assume the ID of an object is 123, then it could appear in a URL:

https://gavinjl.me/address/123

It could appear as a query parameter in a URL:

https://gavinjl.me/address?ID=123

It could also appear as a request header:

Request-ID: 123

Or part of the request body, as XML or JSON:

{ "ID": 123}

These could all be legitimate requests to an API where the user is allowed access to the address record with an ID of 123.

To get at your objects, an attacker needs make a request to the API using one of your IDs. There are a number of ways they can get one:

  1. Guess - if, as in our example, the ID is a number, then the attacker could be a user who has an address with the ID 122. It would be simple to alter a request and add one to that number, getting 123.
  2. Brute force - maybe the ID is a larger number, maybe it contains letters, or dates. There are lots of free tools that allow brute forcing identifiers in web requests
  3. Discover it - if the ID appears in the URL then it is more likely to be logged or stored somewhere. Logs are only likely to be accessible by owners of the API. If this was a regular web request then the URL could be sent in an email, stored as a bookmark, or stored in the browser history. As we're focusing on API calls here then that's less likely.

Why does the Attack Work?

There are two types of authorisation involved here:

  1. Vertical - users fit into categories or roles. Those roles could be given names like anonymous, shopper or admin. Anonymous requests shouldn't be allowed to perform the actions that the shopper or admin role should and a shopper shouldn't be able to perform some of the actions that an admin can.
  2. Horizontal - users have objects that either belong solely to them, or at least can be accessed by them. Other users have access to their own objects, but without explicit permission, shouldn't be able to access yours.

It's specifically a failure in the horizontal access control that allows this attack to work, although an attacker may be limited to which requests they can make in an API according the vertical access they have when making requests i.e. if the attacker is in the shopper role and the vulnerability is on an admin only endpoint, then the attack won't be successful.

This also means that this attack typically requires the attacker to have access to the API, so they may have to sign up for it or even purchase access if needed.

What is the Impact?

If the API has been made without any horizontal access control then an attacker may be able to perform any action that expects an ID in the request. Potentially reading, updating or deleting objects that belong to other users.

If you're hoping to defend from this attack then I've got a Pluralsight course on secure coding, which might just help!

Here's a preview: