Insecure Direct Object Reference
Research / Posted September 25, 2020
Despite sounding like a character in HBO’s hit TV series Game Of Thrones, IDOR, or “Insecure Direct Object Reference”, is in fact a common web application vulnerability that allows an attacker to bypass mis-configured logical access controls and access sensitive data.
In this article, we will step through looking at what IDOR is, how it can often be introduced as a vulnerability, how an attacker is able to exploit it, and how to defend against it.
Subjects & Objects
Logical Access Control is the term used to describe the selective restriction of access to a resource, placing limits on the ability to perform “CRUD” operations (Create, Read, Update, Delete) upon that resource. Permission to access a resource is typically called authorisation. There are a number of possible access control models, but all rely on the concept of subjects who can perform actions on a given system, and objects to describe the resources or entities that require regulated or controlled access.
Static Web Object Access Patterns
In dynamic web applications, an object could be a static resource such as an image. Let’s consider an example of a static resource located at a URL such as:
Images are not typically protected by access control in most systems, but let’s assume that it is for the purposes of this example. If we wanted to enforce access control (i.e. restrict which subjects can access this object) then the most basic form of authentication would be to provide for a binary or Boolean determination of access – a check for whether a given user (subject) is authorised to access this resource, by providing valid identification (userID) and authentication (password) to the system. In this scenario, which userID you are doesn’t specifically matter – you either have a valid userID/password combination (hence are permitted access to the object) or else you don’t have a valid userID/password combination (and so are denied access).
Dynamic Web Object Access Patterns
However, the majority of access that is regulated in rich web applications uses a more complex form of authorisation in which it matters very much which user ID is provided. In this pattern, a more advanced form of authorisation is implemented in which an authorisation policy which associates users with the resources they are allowed to access is used.
Imagine for instance a dynamic web page that is generated for the “MyAccount” page of an online bank at https://www.example.com/myaccount – clearly it matters quite a bit which userID is provided, since you want to see your own bank balance and to take actions on your own accounts, not someone else’s.
The content returned is not, as in the static image example, a simple and unchanging resource, but rather a dynamic web page typically stitched together from a template and per-user specific records pulled from a database, such as the user’s balance. The system therefore needs to apply “Horizontal Authorisation” in these situations – two or more users have the same privilege level but must be prevented from accessing each other’s resources. It is a common scenario wherever a system uses key-based access to resources in a multi-user context.
Imagine a functionality in our dynamic web application in which there are a finite number of users and a finite number of objects that they wish to access, such as bank accounts, and where each bank account has its own bank account number or ID. In this instance, we can’t simply call a URL such as https://www.example.com/account because the user may have multiple accounts (e.g. current account and savings) – the dynamic web application needs some method of for the client to communicate which resource (object) is being requested or acted upon.
One common way of delivering the ability of one client to multiple resources (objects) is to indicate the resource ID in the HTTP request, either as a POST variable, or a GET URL parameter:
POST account.asp HTTP/1.1
Mistakes Were Made (What Goes Wrong)
This is where mistakes often creep into code. When a requesting user (subject) supplies input to the system (such as a bank account number), then the developer has created a situation in which the user is directing which resource should be accessed. If the code fails to ensure that the object permits access by the user in question, then a subject may be able to access the resource when they should not be permitted to. The fundamental question is – if the user changes the key that maps to a given resource, what happens? A typical manifestation of this weakness is when a system uses sequential or otherwise easily-guessable IDs that would allow one user to easily submit a different ID. For example, the user instead tries to access account “11112345” by changing the parameter in the request manually:
Does the system permit them access? If so, then the vulnerability is present. It is variously described by a series of somewhat clunky monikers including “Insecure Direct Object reference (IDOR)”, “Authorisation Bypass Through User-Controlled Key” or “Improper Control of Resource Identifiers”.
The primary cause of the vulnerability being introduced is conceptual lack of clarity by developers about how the resource access should be controlled. Typically, an access control measures will be put in place by the developer, but of the wrong sort. That is, they might perform a check such as “is the user logged in”, and “is the account ID valid?” – but the slightly more abstract question “is the ID appropriate to be accessed by the subject in question” may not be asked, maybe assumed to be handled by a function elsewhere in the code, or else the code retrieving the resource may not be provided with the context of what the requesting subject (user ID) actually is.
Potential Impact & Variants
So, what is the impact of the vulnerability? For such a conceptually simple vulnerability, IDOR remains extremely prevalent in web applications to this day.
The most typical impact is that in our example, known as “horizontal escalation of privilege”, which one user is able to directly access the information of another user at an equivalent privilege level, by modifying a key in the request. However “vertical escalation of privilege” is also occasionally possible if the user-controlled key either:
- Controls access to a “mixed” bundle of resources at different privilege levels, in which some are owned by administrators; or else
- the key does not itself directly relate to a specific resource but is rather a flag that indicates administrator status, allowing the attacker to gain administrative access.
The potential impacts therefore include:
- The unauthorised retrieval (read) of a resource or data record (unauthorized information disclosure);
- In the case where the POST method is used and a resource is updated rather than fetched, the unauthorised modification or destruction of data; or
- Potentially, gaining access to one or more privileged or administrative functions outside of the limits of the requesting user
IDOR Prevention & Mitigation
The best approach to prevent IDOR is to ensure that where user-provided input is used to control resource selection, that the index keys used are locally-unique rather than valid in a global context and the actual resource ID is not presented externally or controlled via user input. That is, that a user requests access to “their” first account using a URL such as:
and the database is able to lookup the account ID to be accessed within an internal table, e.g.:
Salted Hashes for IDs
The approach above is only possible where each resource maps on a one-to-one basis to a specific user. Where this is not possible, and an object (resource) has one or more possible valid authorised users that can access it, then one potential solution is to generate “pseudo-IDs” on the front end from a different address space and that are resistant to “guessing” or incrementing. This can be done using a strong and collision-resistant hash function (including a salt unknown to the user) to calculate a hashed value to be used on the front end for all user interaction. Our URL for access the account 18749934 may now be:
In addition to preventing IDOR vulnerabilities in your in-house code, it is important to find examples where IDOR may be present in your online web application, whether from legacy in-house code, from third-party libraries and systems, or from commercial or open source systems you may have deployed for specific functionality, such as blogs.
IDOR is traditionally difficult for vulnerability scanners to detect without the context of a human operator. However, AppCheck can detect IDOR in your application using advanced vulnerability scanning techniques. AppCheck will look for common PII data in returned server responses and determine if the returned data changes when cycling input numeric parameters.
It is important to remember that while numerical IDOR is the most well known example of this vulnerability, other types exist. Mongo ObjectIds for instance are 12 bytes and usually represented as a hexadecimal string such as 5f633afc115dcb70c2337a0b, to the naked eye these may appear to be unpredictable values and suitable for use without additional access control. However, these ObjectIds are composed of a timestamp, machine identifier, process identifier, and counter or a timestamp, a random value, and counter (depending on version) concatenated together before being represented as a hexadecimal string. Therefore given an example of a valid ObjectId from the system an attacker can generate a large number of ObjectIds that may have been created by the system just before or after the known example, and use these in an attempt to access resources they should not be permitted access to. But don’t worry, AppCheck is able to detect this variation as well!
How can AppCheck Help?
AppCheck can help you with providing assurance in your entire organisation’s security footprint. AppCheck performs comprehensive checks for a massive range of web application vulnerabilities from first principle to detect vulnerabilities – including IDOR – in in-house application code. AppCheck also draws on checks for known infrastructure vulnerabilities in vendor devices and code from a large database of known and published CVEs. The AppCheck Vulnerability Analysis Engine provides detailed rationale behind each finding including a custom narrative to explain the detection methodology, verbose technical detail and proof of concept evidence through safe exploitation.
Get a free vulnerability scan for your business
As always, if you require any more information on this topic or want to see what unexpected vulnerabilities AppCheck can pick up in your website and applications then please get in contact with us: firstname.lastname@example.org
Get started with Appcheck
No software to download or install.
Contact us or call us 0113 887 8380