To find IDOR, hackers intercept API requests and substitute new identifiers into them using a web proxy, such as BURP Suite. Sometimes they rely on luck and brute-force IDs, but there are more elegant techniques, such as swapping session labels.
To find IDOR:
You need to create two users and save their session labels.
This can be a token or a session ID, which is any string in the API that the application uses to identify the logged in user.
The next step is to log in as the first user, perform a series of actions in the application and record them using a proxy.
Now we need to look at the traffic and find the API call that passes the object ID to the server.
You need to repeat the call, intercept, edit and send to the server with the session label of the second user.
If as a result the server responded with an authorization error, the IDOR is most likely missing. But if the backend returns data about the object, you need to compare the responses to the normal and malformed requests. If they are the same, the application is vulnerable.
In BURP Suite, such checks are partially automated using plugins: AuthMatrix or Autorize. They get rid of the routine and allow you to filter the results (for example, in Autorize using the Scope items only flag and regular expressions). However, these plugins are just a handy tool, the main thing in such bug hunting is experience and understanding of how the application works.
You need to find out what roles and groups are provided in the application and how they interact.
What is the difference between manager, driver and administrator and what functions are available to each of them?
It is desirable to build a map of relationships between resources.
How are orders, checks and goods related? Can one user place orders under someone else’s name?
It is worth exploring the features of the REST API.
This set of rules forces developers to act in a pattern that can be used against them. Let’s say you find an endpoint that exposes a REST resource.
Try replacing GET with another HTTP method. If that doesn’t work, add a Content-length HTTP header or change the content type.
Why there are so many IDORs
In the past few years, IDORs have been everywhere, with several in one, even a small application. It seems to me that there are objective reasons for this:
More identifiers are sent from clients.
In the past, the server could directly track user actions, but in modern applications, clients are increasingly passing more data on request through an API.
The old IDOR defenses are no longer used.
Developers often replaced real object IDs with temporary ones that are relevant only for this user and one session. To do this, a separate table was created on the backend, where each object had a temporary identifier. This practice has lost its relevance, because it does not agree well with the principles of the REST API. In addition, this interface no longer provides for recording the state of the client (Stateless).
Role models are getting more complex.
Even if an application has a robust mechanism for checking user rights, it needs to be properly configured. It can be difficult for a developer to know if user X has file Y available. Especially if the user is a regional manager who belongs to one of a dozen subtypes within the role model. Another setting of the authorization mechanism complicates the misunderstanding between developers and end users of the system. As a result, users are often left with redundant options just to avoid accidentally selecting the features they want.
Defending and Eliminating IDOR Are Not the Same Thing
There are many recommendations on the net to combat IDOR, but many of them are confusing. The authors of such tips often list methods to mitigate the risk of a vulnerability and pass them off as ways to fix it. I mean recommendations like:
Use of random identifiers.
Most programming languages provide cryptographic functions that generate a new value with high entropy. If you use them to create object identifiers, it will be more difficult for attackers to pick up a new ID to exploit IDOR.
The use of hashes.
Another way to make it difficult to change identifiers. It is given, for example, in the OWASP memo. However, hashes can be guessed. By the way, Base64, which is sometimes used as such, although it is not a hash function, decodes without any problems.
Using JWT JSON Web Tokens.
Such tokens protect against some manipulation of user IDs, but do not solve problems with object IDs.
Filtering user input before it is processed by the application, validating ranges, lengths, and formats.
Perhaps the most useful of these recommendations, the main thing is to correctly configure the filter.
However, none of these methods solves the problem of access control, does not eliminate IDOR. They only make the problem worse. By the way, external security systems, such as web application firewalls, do not save from this type of vulnerability.
The fact is that IDORs are closely related to the business logic of the application. The only way to reliably mitigate IDOR is to fine-tune session management and user access checking at the object level. This way, even if an attacker finds and changes the internal link, he still won’t gain unauthorized access.
Of course, every application is different. There is no universal way to implement access control, but in any case, this mechanism should be well designed and tested according to certain patterns.
It’s worth checking out a scenario in which a low-privileged user tries to perform actions meant only for high-privileged users. The verification scheme is similar to the one used in hacking.
Log in to the application under an account with the highest privileges.
Perform a series of actions in the application and record API requests using a proxy.
Authenticate to the application with a lower privileged account to generate a token for the Authorization header.
Replay recorded API requests with title changed using a low privilege user token.
The next step is to develop and run unit tests to cover edge cases – situations where:
The user is not authenticated, for example, the authorization header is missing or invalid.
The user is authenticated but not authorized on the resource.
Finally, full integration testing is required, taking into account edge cases. When testing an API, it is desirable to test each method for each endpoint. Unfortunately, there is no silver bullet from IDOR – only testing, testing and more testing.