Insecure Direct Object Reference or IDOR happens when an application inadvertently exposes private objects through user input. For example, a website may let you access private customer profiles by entering unique user IDs into the URL like this:
The danger, of course, is that an attacker might create a bot that iterates through the integer in order to scrape sensitive information. This attack vector is especially salient if the ID value is incremental, as each successive integer is guaranteed to be another account. Ultimately, this is an access control vulnerability, as an unprivileged stranger may use user input to gain access to things they shouldn’t.
Types of IDOR
IDOR attacks could appear in different forms. Usually, a human could easily spot these vulnerabilities by inspecting the HTTP traffic via proxy, sometimes when the vulnerability relays in the URL, a simple browser would do the job.
Once inspecting the HTTP traffic, one should look at the direct and indirect effect of a user’s input on the server’s returned objects. Most commonly-used such user’s inputs are:
- Incremental integer: Like in the above example, when resources are accessible through an incremental integer parameter, which is usually a key in a table, that can be easily iterated through.
- Dates: Likewise, dates can also be iterated through.
- Predictable strings: files that store confidential information with names like “ID-” + username + “.txt”.
Ultimately, mitigating IDOR comes down to having a robust access control system in place. For example, a website may check to which account a user is logged-in to before displaying a profile, or not letting non-admin users download certain files. That way, even if an attacker can manipulate parameters to reveal non-public objects, unauthorized access is rejected.
Many recommend using hard-to-guess parameter values so that iterating through them is difficult if not outright impossible like UUID or any high entropy hash. While it is important to do so, this could open other attack vectors when these ids are leaked, like what was discovered in the Uber mobile app.
These ids are usually stored as “display id” which is what the application exposes to the user, while internally the backend still using the normal id to query the database, join tables and more.
This OWASP cheatsheet, however, suggests another solution: using salted hashes to obscure the direct references.
There are multiple ways to detect an IDOR vulnerability, some techniques are better than others. Over time we learn that manual testing or hybrid testing for such vulnerability is the most accurate one over fuzzing or automated tools.
Traditional fuzz testing is not up to the task. It is designed to detect crashes or malfunctions when a program is supplied with malformed input. But with IDOR, one wants to detect cases where well-formed input works but shouldn’t. For applications that use Swagger to define their APIs, fuzz-lightyear was developed.
There are other automated runtime detection tools out there, but we have seen them failing repeatedly, so we can not recommend any specific one.
Having your application thoroughly penetration tested via careful inspection is what we found works best. A hybrid approach like using Burp Autorize is what we use in our penetration testing which helps the tester.
Common vulnerabilities such as IDOR are important to test against, as leaving these in production environments leads to severe data leaks.