IDOR vulnerabilities are a lot more common than you’d think, and they often hide in plain sight, relying on a simple oversight: the application trusts the client-provided identifier too much.
Let’s see it in action. Imagine a simple web app where users can view their own orders. A typical request might look like this:
GET /orders/view?order_id=12345 HTTP/1.1
Host: example.com
Cookie: sessionid=abcdef123456
If you’re user_A and order_id=12345 belongs to you, you can see your order. But what if you change order_id to 12346?
GET /orders/view?order_id=12346 HTTP/1.1
Host: example.com
Cookie: sessionid=abcdef123456
If the application doesn’t re-verify that user_A is authorized to see order_id=12346, and order_id=12346 belongs to user_B, then you’ve just found an IDOR. Burp Suite is fantastic for uncovering these.
Here’s how to set up Burp to find IDORs:
- Proxy Setup: Configure your browser to use Burp Suite as its proxy (typically
127.0.0.1:8080). Ensure Burp is intercepting traffic. - Target Exploration: Browse through the application as a logged-in user. Visit pages that display resources identified by a unique ID – user profiles, order details, account settings, document views, etc.
- Identify Parameters: Look for parameters in the URL (like
order_id,user_id,account_number,document_id) or in the request body (especially in POST requests) that represent these identifiers. - Repeater: Right-click on a request in the Proxy History or Site Map that contains such an identifier and select "Send to Repeater."
- Manual Testing: In Repeater, systematically change the value of the identified parameter.
- Increment/decrement the ID: Try
12345->12346or12345->12344. - Use known IDs: If you can guess or find another user’s ID (e.g.,
1for an admin, or a sequential ID you’ve seen), try using that. - Randomize: Try completely random values.
- Check for predictable patterns: Are IDs sequential? Based on timestamps?
- Increment/decrement the ID: Try
- Intruder (for Automation): For more systematic testing, right-click a request with an ID parameter and select "Send to Intruder."
- Add Payload Positions: In the "Payloads" tab, identify the parameter you want to fuzz. Click "Add §" around its value to mark it as a payload position.
- Choose Payload Type: Select "Numbers" for sequential IDs. Set "From" and "To" values based on observed IDs. For example, if you see IDs from
1000to2000, set "From" to1000and "To" to2000. Choose "Step" as1. - Grep - Match: In the "Grep - Match" tab, you can add strings that indicate success (e.g., "Order Details") or failure (e.g., "Access Denied," "Invalid Order," "You are not authorized"). This helps filter results. Burp will then send requests with each number in your range and highlight responses that contain your "success" strings.
- Grep - Extract: You can also use "Grep - Extract" to pull out specific data from responses, like the username or order details, to confirm you’re seeing someone else’s data.
- Start Attack: Click "Start attack."
The core of an IDOR vulnerability lies in the application’s failure to perform a proper authorization check after it has identified the target resource using the ID provided by the client. It might authenticate the user correctly, but it forgets to check if that specific authenticated user has permission to access that specific resource ID.
The most surprising thing about IDORs is how often they appear in seemingly secure applications, particularly in APIs where endpoint design might be more focused on functionality than granular access control. A common oversight is when an API endpoint is designed to fetch a resource by ID, and the developer assumes that if the user is authenticated, they should be able to fetch any resource of that type, provided they know its ID. This is fundamentally flawed because authentication confirms who you are, while authorization confirms what you’re allowed to do.
Consider an API endpoint like GET /api/v1/users/{userId}/profile. If you’re logged in as user_id=101, and you make a request to GET /api/v1/users/102/profile, the API might successfully authenticate you using your session token, then use 102 to fetch user_id=102’s profile data without checking if user_id=101 has permission to view user_id=102’s profile. This bypasses the intended access control.
The next conceptual hurdle is understanding how to leverage these vulnerabilities for more complex attacks, such as privilege escalation or data exfiltration.