IDOR explained – OWASP Top 10 vulnerabilities
Hello ethical hackers and welcome to this new episode of the OWASP Top 10 vulnerabilities series. In this blog post, you will learn all aspects of the IDOR vulnerability. You will start with the basics and gradually build your knowledge. When you finish reading this article, you will have a solid understanding of IDOR. Besides, you will be ready to put your knowledge into practice in the IDOR tutorial.
I will keep enriching your mind with knowledge and skills through similar upcoming content, so make sure you don’t miss any chance and subscribe to our newsletter.
What is IDOR?
IDOR stands for Insecure Direct Object Reference. Let me break that down for you. I will make key concepts in bold so that it’s easier for you to connect the dots and understand IDOR meaning.
Typically, every application has to manipulate resources. For instance, an e-commerce website will manipulate products, users, baskets, etc. Each resource instance will be called an object, and it is generally referenced by an ID. For example, user A will have ID1 and user B will have ID2. IDOR vulnerability targets a flaw in the way the application references these objects. In other words, any insecure or lack of validation can lead to a malicious user directly accessing unauthorized resources.
I tried to put all the keywords into place. Hopefully, this makes sense for you now. If it is not clear, don’t worry. The following sections will make it crystal clear.
IDOR falls into the OWASP Broken Access Control vulnerability category. This means that you will find most of the IDOR vulnerabilities after you authenticate to the application. However, it’s not always the case.
IDOR attack using guessable IDs
The most basic IDOR scenario happens when the application references objects using easy to guess IDs. For example, they can be incremental integers, they can contain predictable words like the email of the user, or a folder name. Sometimes, they can be poorly encoded. For instance, a base64 encoded incremental Integer, or a profile image name hash reference.
Suppose that an application lets you access your data on the following endpoint:
GET /api/users/78963
In this simple scenario, all you have to do is substitute your ID, which is 78963
, with another guessed value.
If the ID is a file name, try /etc/passwd
. If it is an Integer, try looping through a range of them.
In the Insecure Direct Object Reference tutorial, you will practice these kinds of attacks.
IDOR attack using IDOR with GUIDs
Sometimes, the application uses IDs which are hard or even impossible to guess. In this case, it is most likely to be a Globally Unique Identifier (GUID). You can also find it under the name of Universally Unique Identifier (UUID). To continue on the example we gave earlier, the endpoint might look like the following:
GET /api/users/b10b413c-6b52-4b10-98c3-b74d19c4e0f6
In this case, you can perform more enumeration on the application. In other words, try to discover as many features as you can. You will likely find endpoints which return a list of objects, each one referenced using a publicly available GUID. For example, the user public profile might return its GUID.
If UUIDs are not publicly available, you can still test for the IDOR vulnerability. Although the impact might be lower, I’ve seen many instances where the issue has been accepted by the client as valid. Moreover, if there is a CSRF issue or a CORS misconfiguration, you can exfiltrate UUIDs and forge your malicious requests with ease.
IDOR in REST applications
In most modern applications, you will deal with REST APIs, which follow a simple naming convention. I will explain key points about REST APIs, which would help you understand how to test for IDOR. You can learn more about the REST convention, but I will explain what you need for a successful IDOR exploit.
With that said, this doesn’t mean that you won’t find insecure direct object reference vulnerabilities in other Web Service styles like SOAP. Whenever you see a feature working with an object reference, always try testing for IDOR.
REST HTTP methods
You can also call them HTTP verbs. These define the operation to execute on the API. In general, the GET
method allows you to read data, the POST
will either create or update a resource, the PUT
and PATCH
verbs update data and DELETE
will delete your referenced resource(s).
REST convention
REST applications follow a naming convention which makes it easy for you to uncover hidden IDOR vulnerabilities.
For the sake of simplicity, let’s say an application manages users using incremental Integers. Through your usual enumeration, you found this endpoint which returns your profile data:
GET /api/profile
If it is a RESTful API, you can test many things!
Firstly, try to append an ID to the endpoint. You might stumble upon the administrator or the owner using small integers.
GET /api/profile/1
Then, you can test the update of a user.
PUT /api/profile/1
Host: vulnerable
Content-Type: application/json
{"email": "eve@evil.com"}
You can also test reading all the profiles
GET /api/profiles
Finally, you can test creating a new user.
POST /api/profile
Host: vulnerable
Content-Type: application/json
{“email”: “eve@evil.com”, “password”: “123”}
Of course, things are not so simple in real life. However, the methodology of testing for IDOR vulnerabilities still applies. We will explore more realistic examples in the IDOR tutorial.
IDOR and mass-assignment vulnerabilities
Sometimes, when you create a new resource, you get back its ID. However, when you update it, the application doesn’t include it in the POST data. For instance, suppose an application manages a to-do list. The following request creates a new one:
POST /api/todos
Host: vulnerable
Content-Type: application/json
{"name":"mytodo"}
Then, you get the following response: {"id": 123, "name":"mytodo"}
However, when you update it, the request doesn’t reference the ID in the POST data.
PUT /api/todos/123
Host: vulnerable
Content-Type: application/json
{“name”:”mytodo”}
You might be tempted to change the ID 123
in the request endpoint, but the application checks if you have the right to update it.
This is where mass-assignment comes into play. If the application updates all attributes specified in the POST data, you can send the following request:
PUT /api/todos/123
Host: vulnerable
Content-Type: application/json
{“name”:”mytodo”,”id”:1}
Therefore, you bypass the check and the to-do list with ID 1
will be updated!
A special case of this is when the object you are storing references another object. In his tweet, Jobert explains how referencing a non-existing child ID can result in disclosing data of future objects.
In the next section, I will show you some IDOR real life examples.
IDOR attack examples
Let’s start with this simple IDOR vulnerability PoC to show you how easy it is to find this vulnerability in the wild. In this case, all the hacker had to do was to loop through the order numbers, which are incremental integers. This led to disclosing arbitrary users’ order information. Notice how the endpoint follows the REST naming convention /order/ORDER-ID
Then, there is this IDOR hackerone report where the hacker can update a resource using the id, which is a simple integer. Note the hacker’s methodology, we will come back to this in the following section.
Finally, this IDOR exploit is quite interesting. In fact, the hacker decodes a base64 encoded ID and finds that the team ID is guessable. He then references new teams by changing the ID and encoding it in base64.
Insecure direct object reference impact
IDOR impact varies depending on the context. Firstly, it can lead to confidentiality compromise, like sensitive information disclosure. For instance, as you saw in the first IDOR Hackerone report, orders of arbitrary users have been leaked. Secondly, IDOR can allow an attacker to edit unauthorized resources as you discovered in the second IDOR attack example. Finally, Insecure direct object reference can impact availability. For example, an attacker can abuse a feature which deletes uploads to delete a file required by the system, which will lead to a server crash.
How to test for IDOR vulnerability? IDOR methodology and tools
Insecure direct object reference vulnerabilities are easy to find. However, some of them may go under your testing radar if your tests are superficial. Besides, you will get many duplicates if you are a bug bounty hunter.
To maximize your chance of finding hidden IDOR vulnerabilities, here is a methodology you can follow.
- Register two accounts for each role the application supports. This will help you test lateral access control measures and privilege escalation.
- Discover as many features as you can, preferably with the role with the highest privilege. If the application provides paid membership, try to get test accounts or purchase it.
- Collect all the endpoints found and try to find a naming pattern. Then, guess new endpoint names based on the pattern you discovered.
Test for all the endpoints against all the roles you’ve registered earlier. You can manually do that if the application is small and the roles don’t go beyond two. In the opposite case, you’ll need a tool to assist you. In Burp Suite, you can use AuthMatrix, Auto-Repeater or Authorize plugins.
Insecure direct object reference prevention
Insecure direct object reference remediation requires developers to manually define access control measures on each endpoint. Because of this, it is hard to cover all the features. In fact, I don’t remember a single application which passed my IDOR testing. However, the following developer habits might reduce the attack surface and effectively allow for better IDOR mitigation:
- As a developer or tester, make sure to write integration tests which cover IDOR use cases.
- For DevOps engineers, make sure you set up a CI/CD pipeline which includes all automated tests.
- Use GUIDs which are hard to guess. However, this doesn’t help with IDOR fix by itself.
You can learn more on how to prevent IDOR using the insecure direct object reference OWASP cheat sheet.
That’s it! You’re now ready for the hands-on IDOR tutorial. If you enjoyed learning with this article, make sure to share it with your network and subscribe to the newsletter to have fresh content delivered to you once it’s available. Until then, stay curious, learn new things and go find some bugs!