Broken Object Level Authorization With Examples

In this post we explore and discuss Broken Object Level Authorization failure.

We’re going to start by explaining what broken object level authorization means. Then we’ll go through the attack explaining the associated risk factors.

We will then look at some of the possible impacts of the vulnerability before we finally take a look at common defenses.

What is Broken Object Level Authorization

In short, this type of attack means that the authorization applied to data isn’t being done as it should. This leads to access being granted to resources and data when it shouldn’t be.

Broken object level authorization has in the past been known as Insecure Direct Object Reference (IDOR).

When we say the word object in Broken Object Level Authorization, what we mean is a value or a group of values. An object might be a social media post that contains the author, content and post date.

Authorization is all about what a user is allowed to access. Therefore, we are talking about a user who is already logged in.

Broken Object Level Authorization

When a user makes a request to an API, the request is used to access objects. This is the point a decision should be made about authorization. The user should only be able to access objects that they have been granted access to. This is authorization working correctly.

When authorization is broken, users are allowed to access data and resources that they shouldn’t be allowed to.

An API facilitates various operations on objects. We can get, create, update or even delete objects.

Interacting with an object is the whole point of an API, therefore if the authorization controls around those objects are broken, then we have Broken Object Level Access vulnerability.

Exploiting Broken Object Level Access Vulnerability

It is generally easy to exploit this vulnerability once it’s been found. All an attacker needs to do is to change an identifier in a request and they’ve potentially got access to objects they shouldn’t be allowed to.

Let’s see it in an example.

Here, we have a URL that is used to call an API:

https://myemail.com/messages/12345

This API call is used to retrieve a user’s private messages. The resource being used is messages.

The message is the object that we are referring to in the Broken Object Level Authorization. The assumption is that private messages can only be read by intended recipient.

Next, we have the id of the message 12345. This is an important part for an attacker.

The id tells the service which record to return. The API retrieves that record from a data store and return it in the response.

Now what happens if we change the id from 12345 to 12346? e.g:

https://myemail.com/messages/12346

If the message with id 12346 was intended for our user, we should be able to retrieve it.

But if the message belonged to another user, the API should never return it. If we did manage to retrieve the message, then we have a Broken Level Object Authorization failure.

Another example is sending a POST request to update a resource. We can play around with the id in the JSON payload:

{
    "userId": "12345678",
    "oldPassword": "My_0ld_Pa$$",
    "newPassword": "$uperS3CurE"
}

If we were to put any potential userId in the request and were able to update another user’s details, then we have a massive problem.

Technical Impact

Once we know the vulnerability exists, we can exploit it in all kinds of manner. As mentioned before, we can use various HTTP methods on an API. We can use the Id to update or even delete messages!

What happens if we were able to iterate through all Ids? We might be able to delete every message stored. That’s a big impact.

Common Vulnerability

This is a very common vulnerability. As mentioned before, APIs are used to access objects and in most cases we use Ids in the request to identify resources. The question is, are there authorization checks in place for that access?

There are mainly two reasons why we end up having Broken Object Level Authorization vulnerabilities in the code.

The first is that a security control simply hasn’t been implemented. The code hasn’t been written to perform authorization checks on requests.

The second reason is human error. People make mistakes. A good example is in an API that handles both sensitive on non sensitive data. Some requests should have authorization checks and others shouldn’t. So it might be easy to miss a check when writing code.

How to Detect

Automated tools wouldn’t normally find this type of vulnerability as it tends to take at least a little bit of brain power.

It is relatively easy for a human to detect this vulnerability. All we need to do is to find the Identifier that’s being used to retrieve objects.

Note the identifier can be in the Url, in the request body or in the header.

Also we have to analyse and interpret the response that comes back to see if there is a vulnerability or not.

Tools

We can use any tool that inspects the HTTP requests and responses. Some of these are:

  • Google Developer Tools
  • Burp Suite
  • Postman

Burp Suite can also be used to automate some of the requests.

Defending Against Broken Object Level Authorization

We’ve got two defenses here.

The first defense is to use unpredictable Ids such as GUIDs. When we use consecutive numbers in the code, e.g. 12345, this means Ids are very predictable. An attacker doesn’t need a lot of effort to go through numbers in order to find objects.

An example of a GUID:

d3b773e6-3b44-4f5f-9813-c39844719fc4

GUIDs are complex and very hard to guess and are not sequential.

The next defense is to actually have some code to check authorization. This check often just doesn’t happen.

Checking authorization should happen any time that a user presents the API within an Id that’s going to be used. The core principle here is that we shouldn’t ever trust data that the user gives to the API.

The requested Id needs to be checked to confirm that the user is authorized to access the object.

These checks could be just simple code reviews during software development and/or automated checks that check for authorization failures throughout the development.

Conclusion

As we’ve seen Broken Object Level Authorization is a common vulnerability and easy to spot and attack. Potential impacts are huge.

The real source of the this vulnerability is trusting data that is passed to the API by the client.

A big part of the defense is to make sure we don’t trust that data. So we need to make sure authorization checks are in place.