IDOR, you DOR, everybody DOR: The dangers of direct object references
Using an insecure direct object reference in your web application might not seem such a big deal, especially if you don’t know you’re doing it. But if anyone in the world is able to access sensitive customer data in your systems just by knowing the address, your company might make the headlines – and not in a good way.
Your Information will be kept private.
Your Information will be kept private.
In web application security, we love our acronyms. Many of them look complicated and indeed refer to complex vulnerabilities, but others obscure very simple concepts – like insecure direct object references (IDOR). These are a common bad practice in web development, but a major data leak involving one of Australia’s biggest telcos showed how little it can take to go from bad practice to exposing millions of customer records.
IDOR at your service – an example
We’ve written about IDORs before and even have an Invicti Learn page about them, so here’s just one short example from real life as a tl;dr refresher. Many years ago, an e-learning site I was using emailed me about a special birthday discount for new courses. The link they sent me looked something like this:
https://www.example.com/promo/4061/
Clicking this took me to a birthday discount page offering 15% off. I didn’t need to log in, so this was clearly a generic promo page. I started experimenting with the number at the end of the URL and, sure enough, many of the numbers neighboring 4061 yielded other existing promo pages. Some of the special offers had expired, but others were still valid, and within a few minutes of changing the promo numbers, I found one that gave a 30% discount – double the savings I would otherwise get from my “special” birthday discount.
While this is hardly what you’d call hacking, it is exactly the idea behind insecure direct object references: getting direct access to something that shouldn’t be accessible simply because you know the path. In this trivial example, the only consequence might be a potential loss of revenue if too many customers applied for discounts. In a business application, the consequences can be far more severe – and if you’re a major telecommunications company exposing API access to your entire customer database, they can be catastrophic.
How IDORs made the Optus hack possible
In September 2022, news surfaced that Australian telco Optus had a data breach, exposing nearly 10 million customer records. Unusually for a data breach, fairly detailed and plausible technical information was soon available, as in this full write-up of the incident. In a nutshell, a malicious hacker was able to directly access and enumerate customer records just by working out the right URLs to ask for – and IDORs were a major part of this.
A full investigation is still ongoing as of this writing, but available information suggests a combination of three elementary security blunders:
- Insecure API endpoint: Customer data was accessible through a web API that had either insufficient authentication or (as apparently claimed by the attacker) no authentication at all, enabling the attacker to send data requests to Optus systems.
- Insecure direct object reference: To get a customer’s personal information, the attacker only had to work out (or observe) the URL format and provide a valid customer ID. It appears that no authorization was required – anyone who sent a valid URL would get data in response.
- Predictable identifiers: The customer IDs that were directly used in data requests were based on predictable numbers that the attacker could easily enumerate to find and fetch existing data records.
So it seems that after working out the URL format and finding the right API address to send requests to, the attacker was able to request data for (say) customer #82569934, then customer #82569935, and so on – and get real customer data in response 9.8 million times. (Which, by the way, also suggests missing or inadequate rate limiting on that API.)
Direct access = Bad access control
If all the available information is true, the Optus data breach was a bit like walking into a bank and getting the contents of any deposit box that you know the number of, no questions asked. This is the “insecure” part of IDOR – being able to access an application object (including data) without the application first checking if you’re authorized to do this. While in this case, the IDOR was combined with other security shortcomings, similar issues are common in application security.
In a typical IDOR scenario, you might log in to an application as one user but be able to access another user’s data simply by sending a request with another user ID. This can lead not only to data exposure but also to privilege escalation – horizontal (if you can access the account of another regular user) or vertical (if you can access a more privileged user account). When this happens through an API, unauthorized data access can be automated, with the potential for an Optus-scale data breach.
IDOR happens – but why?
Despite being such a simple concept, IDORs indicate deep-rooted security issues that can be hard to fix and avoid. With a more typical vulnerability like SQL injection, you have a clear cause (unsanitized inputs in database queries) and a clear fix (parameterized queries). With IDORs, the root cause could be anything from hard-coded resource paths to badly designed access control or flawed security assumptions. Especially with APIs, it’s all too easy to assume that authentication or authorization will be handled by another system – in other words, that it’s someone else’s problem.
The only way to eliminate IDOR vulnerabilities is to design and enforce appropriate access control for all internal application objects, such as customer records. Where direct object references can’t be avoided (perhaps in a legacy application), you can at least try to mitigate the “insecure” part of IDOR by using secure hashes instead of actual object identifiers and then mapping them to identifiers internally. This makes it much harder for attackers to enumerate identifiers and access an existing object, but proper access control should still be your primary line of defense.
A little secure design can go a long way
As with the vast majority of security incidents, we will likely never know for certain what made the Optus breach possible. What we do know for certain is that millions of customer records were leaked, the company could face multi-million-dollar fines, and its reputation has suffered. Once breached, organizations will often talk about sophisticated threat actors to suggest that it could happen to anyone, but if you’re leaving your metaphorical doors and windows open, it doesn’t take a genius to accept that invitation. In the Optus case, everything indicates an opportunistic attacker rather than any advanced and organized group.
To prevent fundamental security flaws such as IDORs, application designers and engineers need to know and incorporate object-level access control requirements from the earliest stages of development. Grafting access control onto an existing application or outright assuming that some other system will handle it could result in serious issues down the line. Because if you neglect the basics of secure design, you risk your application sinking before it has even left the harbor.