This article explains Insecure Direct Object Reference (IDOR), an access-control vulnerability where applications authenticate users but fail to verify they own the resources they request. Using a hands-on lab scenario with DocuShare, it demonstrates how an attacker can read another user's document by simply changing a number in the URL, illustrating that authentication and authorization are distinct security controls. IDOR is ranked in the OWASP Top 10 and remains one of the most frequently discovered vulnerabilities in real-world applications and bug bounty programs.
- Authentication versus authorization distinctionThe article emphasizes that DocuShare performs authentication (confirming the user is logged in via a valid session) but skips authorization (verifying the user owns the document). The server receives a document ID parameter, confirms a session exists, and returns the document without ever comparing its owner to the requesting user. This gap between confirming identity and checking permissions is the core vulnerability.
- Sequential IDs enable predictable discoveryIn the lab, Sarah's documents have IDs starting at 1010 and incrementing upward (1010, 1011, etc.). Because IDs are sequential and visible in the address bar, an attacker can simply decrement the number to find other users' documents nearby, making the vulnerable resource trivially discoverable. The lab is solved by changing the ID to 1003 to access the administrator's confidential file.
- Server-side ownership check is the fixThe article prescribes that for every request, the server must load the requested object and verify the current user owns it or has been granted explicit access. This check should be centralized in one place, such as a policy layer, to prevent new endpoints from accidentally omitting the authorization step and to ensure consistent enforcement across the application.
- Unguessable IDs provide limited protectionWhile using UUIDs instead of sequential numbers makes IDs harder to guess, the article clarifies this is a 'speed bump, not a fix' because IDs leak through shared links, logs, error messages, and other responses. Random IDs reduce discoverability but do not eliminate IDOR if the server still lacks proper ownership verification.
- Real-world impact demonstrates severityThe article cites the 2019 First American Financial breach, where approximately 885 million mortgage-related records—including bank details and Social Security numbers—were exposed through URLs with sequential document IDs and no access control. This demonstrates that IDOR is not theoretical; it has directly compromised sensitive financial and personal data at scale.
- IDOR ranks within broken access controlThe article places IDOR within the broader category of Broken Access Control, which is ranked number one in the OWASP Top 10 (2021). IDOR is noted as one of the most common findings in bug bounty programs, particularly in APIs, indicating widespread prevalence.
- Two-account testing methodologyThe article recommends testing for IDOR by creating two accounts and attempting to access account B's data while logged in as account A, checking every ID encountered in URLs, JSON bodies, headers, and file names. This practical approach allows developers and security testers to identify the vulnerability before deployment.
Bottom line: IDOR is a fundamental access-control flaw where authentication succeeds but authorization is never checked; the fix is mandatory server-side verification of ownership for every object access, not reliance on obscuring IDs. Testing for IDOR with two accounts is the most reliable discovery method, and its prevalence in bug bounties and real breaches makes it a critical security priority.
📋 In this walkthrough
What this lab teaches
Insecure Direct Object Reference (IDOR) is an access-control bug. The application uses an identifier you can see and change, such as a number in the URL, to fetch a record, and it never checks whether you are allowed to see that record.
The key lesson: authentication (who are you?) is not authorisation (are you allowed to do this?). DocuShare does the first and skips the second.
How DocuShare loads documents
You are logged in as Sarah, user 42. Your documents have IDs from 1010 upward, and the app opens a document from a doc parameter. The server confirms you have a session, then returns whatever document matches the ID. The lab is solved when you open the administrator’s confidential document.
The attack approach
- Open one of your own documents and note how its ID appears in the request.
- Notice the IDs are sequential. Predictable numbers mean other users’ documents are nearby.
- Change the ID to a lower number and see whether the server refuses or hands it over.
- Keep going until you find a document that belongs to the admin.
Full walkthrough (spoiler)
Stuck after a few attempts? Open the steps below. Solving it yourself first is worth more XP, and more learning.
Show the step-by-step solution
- Open one of Sarah’s documents and look at the document ID it uses.
- Use the helper input below the document list to request a lower document number.
- Work down the range. The server returns other users’ documents without complaint, because it only checks that you are logged in.
- Open the document with ID 1003, the admin’s confidential file. The lab detects it and marks you solved.
Why it works
The server trusts the ID you send. Its only check is “is there a valid session?”, and you have one. Nothing compares the document’s owner with the user asking for it. Sequential IDs make the gap easy to find, but they are not the root cause: even random IDs would leak the moment one appeared in a shared link or a log.
Where this happens in the real world
In 2019 First American Financial exposed around 885 million mortgage-related records, including bank details and Social Security numbers, because documents were served from URLs with sequential numbers and no access check. IDOR falls under Broken Access Control, which is number one in the OWASP Top 10 (2021), and it is one of the most common findings in bug bounty programmes, especially in APIs.
How to defend against it
- Authorise every request on the server. Load the object, then confirm the current user owns it or has been granted access.
- Centralise the check in one place, such as a policy layer, so new endpoints cannot forget it.
- Use unguessable IDs (UUIDs) to reduce discovery, but treat this as a speed bump, not a fix.
- Test with two accounts. Swapping IDs between a user A and user B session is the fastest way to find IDOR in your own app.
Try it, then go further
Reading about it is the easy part. Open the lab, try your own approach before peeking at the spoiler, and see how many attempts it takes.
