2 Million Users at Risk: Unveiling a Critical IDOR Vulnerability

Introduction

Sometimes, the most critical vulnerabilities aren’t found in elaborate penetration tests or bug bounty programs—they’re discovered unexpectedly. While casually exploring the functionality of an online platform, I stumbled upon a serious Insecure Direct Object Reference (IDOR) vulnerability. This flaw, simple yet devastating, exposed the personally identifiable information (PII) of over two million users, leaving their sensitive data easily accessible to anyone with minimal technical know-how.

What struck me most was how easily this data could have fallen into the wrong hands. With no authentication barriers preventing unauthorized access, this issue highlighted a glaring gap in the platform's security measures.

In this blog post, I’ll share the journey of uncovering this vulnerability, the technical details of how it worked, the responsible disclosure process I followed, and the broader implications for web application security. This case underscores an important truth: even a minor oversight in access control can have major consequences.

What Is An IDOR?

Insecure Direct Object References (IDOR) are a type of access control vulnerability in which a web application uses user input to access objects directly lacking correct authentication.

Consider the following URL as an example:

https://somebank.com/get_transactions?customer_number=123

Here, the customer number is used directly as a record index in queries that are performed on the back-end database. A web application vulnerable to IDOR would allow an attacker to change the customer_number from their own customer number (123) to a different customer number and display the victims transactions without requiring any authentication.

Findings

When browsing websites and applications I haven’t used before, I often take a moment to examine the JavaScript files. This habit serves two purposes: it satisfies my curiosity and helps me further my understanding of how different applications are built and function. By diving into these files, I can get insights into how client-side logic is implemented, identify any libraries or frameworks in use, and sometimes even uncover interesting details about the application’s architecture.

While this is primarily an educational exercise, it occasionally reveals unexpected behaviors or potential security issues, such as hardcoded keys, exposed endpoints, or poor practices that could be exploited. It’s fascinating how much information developers unintentionally leave exposed in client-side scripts.

The web application in question utilizes ajax to fetch data from the backend and serves it to the customer. While browsing the JS files I discovered the following routing for a deprecated ajax request:

This get_driver_details method makes a call to the backend to request details of a driver specified by their customer ID which is taken as "customer_id". The application displays your customer ID on the homepage, using my customer_id I visited the following URL:

https://##.########.ie/ajax.php?action=get_driver_details&customer_id=2415488

As expected I’m served a neat JSON response displaying my full name, customer ID, address and phone number amongst some other information. Surely I can’t just alter the customer ID and the associated users information, right?

To my surprise, changing 2415488 to 2415487 and visiting the URL displayed customer details that were most definitely not mine, testing this again with a different customer ID displayed a different user's information, confirming the presence of an IDOR vulnerability.

In practice, an attacker could write a simple script to iterate through every customer ID, save all of the requests and compile a list of all 2 million customers that have registered an account. This customer information could then be used for further attacks or sold for a large sum of money.

Disclosure

Typically an organization of this size will have a security.txt file within the /.well-known/ directory of the website, in this organizations case they did not and still do not have a security.txt file at the time of writing meaning I had some digging to do to ensure I responsibly disclosed the vulnerability to the right person.

Firstly using LinkedIn I attempted to find the name of the CISO or security manager for the organization but seemingly couldn’t find them as one didn’t exist. My next best option was to find the director. Using news sources I confirmed the name of the director and used RocketReach (https://rocketreach.co/) to identify his corporate email.

By browsing various documents on the vulnerable website I confirmed the naming convention for their email addresses are [email protected] and the email on RocketReach matched this naming convention.

23 Feb 2024, 14:19 - Email sent to director to notify of vulnerability and ask for information of their security team.

23 Feb 2024, 17:09 - Director replies asking for details of vulnerability.

23 Feb 2024, 17:32 - Email sent to director with full POC and vulnerability details.

27 Feb 2024, 11:15 - Re-tested vulnerability to confirm it was patched over the weekend and emailed to confirm this.

28 Feb 2024, 08:37 - IT Manager replies asking to confirm the IP addresses I used to find the vulnerability to ensure that nobody else had abused it and also confirmed I had not retained any PII of customers.

Lessons Learned

Even with close to €2bn revenue, this organization had a glaring security issue waiting to be exploited by a bad actor. This case underscores the importance of routine penetration testing - had they conducted thorough security assessments, this issue would likely have been caught before I stumbled upon it, and if I hadn’t have stumbled upon it and was exploited they could have faced massive fines.

The absence of a clear security disclosure process (like a security.txt file) made responsible reporting more difficult. Stronger security practices and proactive testing are essential, no matter the size of the company.