What is IDOR? Why access checks matter
Author: Domeny.ForSale editorial team Published
In brief: IDOR (Insecure Direct Object Reference) is a vulnerability that lets someone access another user’s resource by supplying its identifier, without proper permission checks. For example, a user changes the invoice number in a URL and sees another customer’s document. The problem is not the number in the URL itself, but the server’s failure to check whether that person is entitled to access the invoice.
How IDOR works — a simple example
Imagine a customer portal where you log in to download your own invoice. Your browser sends the server a request for the path /invoices/481, and the application returns document number 481.
There is nothing unusual about using an address like this. The vulnerability arises if changing the path to /invoices/482 lets you download another customer’s invoice, even though you have not been granted access to it.
It is like a cloakroom attendant handing over a coat to anyone who gives a hanger number, without checking whether they are entitled to collect it. The number identifies the item, but does not prove the right to receive it.
The “object” in IDOR means an application resource: a document, order, photo, message or account. A “direct reference” means identifying that resource by its identifier. This does not have to be a sequential number — it could be a filename, an email address or a long string of characters.
Why logging in is not enough
Authentication answers the question: “Who are you?” Authorization, or checking permissions, answers a different one: “What are you allowed to do?” An application can correctly identify a logged-in user yet still give them access to someone else’s data.
A secure server should check not only whether an invoice exists, but also whether the user is allowed to read it. Access rights may come from ownership of the document, a role within an organization or a deliberate decision to share it with another person.
IDOR is not limited to viewing information. Missing checks can also allow someone to modify or delete another user’s resource, such as a delivery address in an order. Permission to read does not automatically grant permission to edit, so each operation requires an appropriate check.
If the application serves multiple companies, the boundaries between organizations matter too. An administrator at one company should not gain access to another company’s data simply by knowing a document’s identifier.
Where a vulnerable identifier may appear
The identifier does not have to be visible in the address bar. It may appear in query parameters, in the body of a request sent by a form, or in a call to an API, an interface that allows programs to communicate.
Common operations that require checks include:
- downloading invoices, attachments and data exports;
- reading messages, support tickets and orders;
- updating a profile or account settings;
- deleting files and other resources.
Gaining access after changing an identifier does not always indicate a flaw. A public blog post should be available to everyone, and a shared document should be available to authorized collaborators. What makes it a vulnerability is a breach of the intended access rules, not simply the ability to specify a different object.
Similar flaws in an API are sometimes described as BOLA (Broken Object Level Authorization), meaning faulty permission checks for a specific object. The terms are closely related; the practical question remains the same: does the server check whether the user is entitled to access the specified resource and perform the requested action?
What actually protects against IDOR
The fundamental safeguard is server-side permission checking whenever a resource is accessed. Hiding a button in the interface is not enough, because a request can be sent without using that button.
In the invoice example, the application should search for the document within the set available to the user, or check permissions before returning it. It should not trust an “owner” field sent by the browser as proof of ownership.
Random identifiers, such as UUID, make addresses harder to guess, but do not replace authorization. If an identifier leaks, for example through a shared link, the server must still deny access to anyone without permission.
A good rule is to deny access by default: if the application cannot confirm permission for an operation, it does not perform it. Checks should also cover file downloads and exports, not just the document’s main screen.
How to test your own application safely
Only perform this test on a system you own or have permission to test. It is best to use a test environment and fictional data, especially when testing modification and deletion.
- Create two test accounts, A and B, with no resources shared between them.
- Use account A to create a document and note its identifier.
- Log in as B and try to read that document through the intended interface or API.
- Separately test editing, downloading and deletion, if those operations are available.
- Check not only for an access-denied message, but also that no data has been disclosed or changed.
The server should refuse the unauthorized operation; it may also deliberately avoid revealing whether the document exists. It is worth adding this scenario to automated tests so that a code change does not reintroduce the vulnerability.
See also: What is 2FA?
