In the modern web, APIs are like the nervous system. They transmit data to and from one endpoint to another and without them, the web, IoT and everything else that’s awesome about tech would not be so amazing.
When something is this crucial, it attracts a lot of attention and requires a lot of thoughts to be put in, while building one. For someone with malicious intent, unauthorized tapping on this nervous system of the web is all it takes to know what is going on within the system and worse, bring down the whole system.
In this article, let’s educate ourselves about the number one vulnerability, which is broken object level authorization, listed in the OWASP 2019 Top 10 API Security guidelines.
We will look at an attack that could be done on an API with this specific vulnerability and we will also look at ways to defend our APIs from such threats.
Irrespective of the role or job title, if one is in the tech industry, it is crucial and beneficial for them to have a basic understanding of the security guidelines to protect their products and organizations from the bad players.
So, let’s get started:
What is OWASP?
OWASP is a nonprofit, open-source foundation whose agenda is to improve the overall software security scenario. If you haven’t heard of them before, please feel free to have a look at their website from the link above to know more about what they do.
The 2019 API Security Guidelines:
Since we discussed how crucial APIs have become in the modern world, OWASP released security guidelines exclusively for APIs that lists the top 10 potential vulnerabilities that could open up an API for an attack. The list can be found here.
Broken Object Level Authorization:
Usually, APIs expose some form of an identifier in the requests sent to them. In most cases, these would be sequential, if the identifier is just the primary key from a backing SQL database. If not given proper attention while creating these sort of APIs, especially when their responses contain sensitive information, the very fact that they have a sequential id in the requests might become a surface for exploit.
Let’s have a look at this with a practical scenario:
Let’s assume that we have a hypothetical list of super-secret products information in our database. We have users in our software system who could access that information through a web portal.
Now, the catch is that not all users are authorized to have access to every product in our category. Certain product information can be accessed by only certain members.
But our system also has other products, which, all users can have the information about.
In our scenario, the product info is the object (in the underlying code, this will be an object representation of a database record). This object is supposed to have specific authorization rules, and each product is going to have a unique id.
You could also think of messages in a chat application. A user shouldn’t be able to retrieve the contents of the chat exchanges between two strangers in which they were not a part of, right? So the message object will have some sort of authorization and also be identified uniquely by an id.
The API Endpoint:
Coming back to our products example,
the API request to retrieve a specific product might look like the following:
In the above request, the unique id for the product is the number tailed to the request:
In our scenario, there are objects that are authorized to be read by only certain specific individuals and there are also objects that can be read by all users.
This creates the chances for auth miss for certain objects which should be permission restricted, as both restricted and non-restricted content are served by the same API.
With sequential and predictable Ids, brute-force attack becomes trivial. especially with certain tools like Burp Suite, these brute-force attacks could be automated and could become very easy to exploit once a vulnerability is discovered in a certain endpoint with a certain id in the API.
The following image shows how easy it is to trigger an automated attack with the intruder tool in Burp Suite:
The attacker could start from a number like 1 and go up to a really high amount in the millions and do a recon for object level authorization vulnerability in just a few hours.
Unfortunately, if we have some auth miss at a specific object level in our API, we will be losing the battle to the intruder here, who would get away with some privileged information, they shouldn’t have had access to in the first place.
One way to mitigate this attack is to use non-sequential unique identifiers for objects. We could use a GUID or UUID instead of a regular sequence. This will make it hard for intruders to use an automated solution to brute-force our endpoints, as the next id will be harder to predict.
Although the mitigation technique might reduce the chances of our vulnerable API from being discovered, it will not prevent it. For that, we have to consciously make sure that all our objects that require an auth goes through an auth process.
This could be made simpler in practice with the following guidelines:
- Have a separate endpoint to access restricted content so that auth miss doesn’t happen by accident or negligence.
- Use some non-sequential unique identifiers like GUID or UUID for the unique identification of the object.
This might seem like an obvious thing to do, but in reality, if you are a startup that is moving fast without much of a security audit on your API endpoints, there are chances that some of your endpoints might end up with this vulnerability.
I hope you found this write-up useful and also believe that the article might have given you some basic exposure to the tools and techniques to test your endpoints for this particular basic security loophole.
Thanks for reading my thoughts,