Modern web applications constantly work with objects: user profiles, invoices, documents, support tickets, orders, messages, images, and API records. These objects are usually identified by some value, such as an ID, UUID, filename, account number, or database key.
The problem begins when an application trusts that identifier without checking whether the authenticated user is actually allowed to access the referenced object. This is the core of an Insecure Direct Object Reference (IDOR) vulnerability.
IDOR remains an important application security issue because modern applications expose large amounts of functionality through APIs and client-side interfaces. A single missing object-level authorization check can expose data across users or tenants. OWASP currently places IDOR within the broader Broken Access Control category, while API security guidance commonly refers to the related problem as Broken Object Level Authorization (BOLA).
For developers and penetration testers, understanding IDOR means understanding something more fundamental than URL manipulation: who is allowed to access a particular object, and where is that decision enforced?
What Is Insecure Direct Object Reference (IDOR)?
Insecure Direct Object Reference (IDOR) is an authorization vulnerability that occurs when an application exposes a direct reference to an internal object but fails to verify whether the requesting user has permission to access that object.
Consider a simple application:
GET /profile/1001
A logged-in user might legitimately access profile 1001.
If changing the reference to:
GET /profile/1002
allows the same user to view another person’s private profile, the application has an object-level authorization problem.
The important issue is not that the ID is visible.
The real problem is that the server accepts the changed identifier and retrieves the object without checking authorization.
OWASP identifies three basic ingredients of an IDOR vulnerability:
- An object, such as a document, account, invoice, or support ticket.
- A reference to that object, such as an ID, UUID, filename, or token.
- A missing or inadequate authorization check for that specific object.
Why Is IDOR Important?
IDOR can expose information that should be isolated between users.
Depending on the application, an attacker may potentially access:
- Personal information
- Invoices
- Orders
- Private messages
- Documents
- Account settings
- Support tickets
- Payment-related records
- Internal business information
- Tenant-specific resources
The impact becomes especially serious in multi-tenant applications.
Imagine a SaaS platform where thousands of companies share the same application. If a request for one company’s invoice can be modified to retrieve another company’s invoice, the vulnerability is no longer just a single-user privacy issue.
It can become a tenant isolation failure.
OWASP recommends enforcing authorization for every request involving a specific object rather than assuming that access to one object automatically grants access to other objects of the same type.
How Does an IDOR Vulnerability Work?
A typical IDOR vulnerability follows a simple sequence.
Step 1: The User Authenticates
The application correctly identifies the user.
For example:
User A ↓Login ↓Authenticated Session
Authentication itself may be working perfectly.
Step 2: The Application Requests an Object
The application sends a request containing an object reference:
GET /api/orders/5012
The server receives the request and looks up order 5012.
Step 3: The Server Retrieves the Object
A vulnerable implementation may effectively perform:
Find order where ID = 5012Return order
The missing step is:
Does the current user have permission to access order 5012?
Step 4: The Identifier Is Changed
During an authorized security assessment, a tester may compare access to objects belonging to different test accounts.
For example:
User A → Object 5012 → AllowedUser A → Object 5013 → Should be denied
If User A can access an object belonging to User B, the application may have an IDOR vulnerability.
The OWASP testing methodology specifically recommends identifying object references and checking whether authorization is consistently enforced when those references are modified.
Where Can IDOR Occur?
IDOR is not limited to URLs.
Object references can appear almost anywhere in an HTTP request.
URL Path Parameters
A common example is:
GET /users/123/profile
The 123 is an object reference.
Query Parameters
For example:
GET /invoice?invoice_id=8451
Changing the identifier may reveal whether authorization is properly enforced.
POST or PUT Requests
Object identifiers can also appear in request bodies:
{ "document_id": "8451", "title": "Annual Report"}
A secure application must authorize the referenced document rather than trusting the submitted value.
JSON APIs
Modern applications frequently expose resources through REST APIs:
GET /api/v1/orders/8451GET /api/v1/messages/312GET /api/v1/files/991
APIs are particularly important because they often expose many object references through predictable request structures.
File References
A filename can also act as an object reference.
For example:
GET /documents/report-user-a.pdf
If changing the filename provides access to another user’s private document, the application has an authorization problem.
OWASP explicitly notes that object references can include filenames, account numbers, tokens, and other values—not only sequential numeric IDs.
Types of IDOR
IDOR is often discussed according to the type of authorization boundary being crossed.
Horizontal IDOR
Horizontal privilege escalation occurs when one user accesses another user’s resources even though both users have the same general privilege level.
Example:
User A → User A's invoice → AllowedUser A → User B's invoice → Unauthorized
This is one of the most common IDOR scenarios.
The attacker does not necessarily become an administrator. Instead, they cross a boundary between two users with equivalent privileges.
Vertical Privilege Escalation
Vertical escalation occurs when a lower-privileged user accesses an object or function intended for a higher-privileged user.
For example:
Regular User → Regular User resource → AllowedRegular User → Administrator resource → Unauthorized
This can overlap with other forms of broken access control.
Cross-Tenant IDOR
Multi-tenant applications require another important boundary.
Consider:
Company A ├── User A1 └── User A2Company B ├── User B1 └── User B2
If a user from Company A can manipulate an object reference and access Company B’s resources, the application has failed to enforce tenant-level isolation.
This can have serious business and compliance consequences.
IDOR in APIs and BOLA
The term Broken Object Level Authorization (BOLA) is commonly used in API security discussions for the same underlying class of problem.
Consider:
GET /api/orders/7821Authorization: Bearer <user-session>
The API may correctly verify that the token belongs to an authenticated user.
But authentication answers:
Who are you?
Authorization must answer:
Are you allowed to access order 7821?
That distinction is critical.
An API can have strong authentication while still having broken object-level authorization.
OWASP’s API security guidance and broader authorization guidance emphasize that authorization must be enforced for the specific object being requested, not simply at the endpoint or user level.
Real-World IDOR Example
Imagine an online shopping application.
A customer views an order through:
GET /orders/45001
The application checks that the customer is logged in.
However, the backend retrieves the order solely by its ID.
Conceptually, vulnerable logic might look like:
order = database.find(order_id)return order
The secure logic needs an authorization relationship:
order = database.find(order_id)if order.owner != current_user: deny accessreturn order
The exact implementation depends on the programming language and framework, but the security principle remains the same.
The server must establish the relationship between the authenticated identity and the requested object.
IDOR Is Not Just About Sequential IDs
A common misconception is that IDOR only exists when an application uses numbers such as:
1001100210031004
That is incorrect.
An application can be vulnerable even when it uses:
UUIDsRandom stringsFilenamesHashesAccount numbersSlugsTokens
If an attacker obtains another valid identifier and the server does not check authorization, the vulnerability still exists.
OWASP specifically warns that complex identifiers do not replace authorization checks.
This is why changing numeric IDs to UUIDs should be treated as defense in depth, not the primary fix.
Predictable IDs and Enumeration
Predictable identifiers do make testing and enumeration easier.
For example:
10001100021000310004
may reveal information about record creation or make unauthorized references easier to discover.
Using random identifiers can reduce this exposure.
However:
Hard-to-guess ID + Missing Authorization = Still Vulnerable
An attacker may obtain a valid identifier through:
- Application responses
- Shared links
- Browser history
- Referrer leakage
- Logs
- Notifications
- Other API responses
- Information disclosure vulnerabilities
The server must therefore remain responsible for authorization.
How to Test for IDOR
IDOR testing should only be performed against applications you own or are explicitly authorized to assess.
The most reliable approach is to use multiple test accounts.
Step 1: Create Two Test Users
Create:
User AUser B
Ideally, both should have the same role.
Step 2: Create Separate Objects
Create resources belonging to each account:
User A → Document AUser B → Document B
Record the object references.
Step 3: Access Your Own Object
Authenticate as User A and confirm:
User A → Document A → Allowed
Step 4: Attempt Cross-Account Access
Still using User A’s session, attempt to request User B’s object.
The expected behavior is denial.
The application should not return the protected object.
Step 5: Test Multiple HTTP Methods
IDOR is not limited to GET.
Check authorization for operations such as:
GETPOSTPUTPATCHDELETE
A user may be prevented from reading another user’s resource but still be able to modify or delete it.
OWASP recommends testing access across read, create, update, delete, export, and administrative operations where applicable.
Tools Used for IDOR Testing
Penetration testers commonly use:
- Burp Suite
- OWASP ZAP
- Browser Developer Tools
- API clients
- HTTP intercepting proxies
- Automated authorization-testing frameworks
Burp Suite is particularly useful for IDOR testing because testers can capture a request, identify object references, and compare behavior between authorized test accounts.
For learners building practical skills, <a href=”https://vuln.pentesthint.com/”>hands-on labs</a> provide a safer environment for understanding authorization flaws without testing systems that you do not own.
Common IDOR Testing Locations
During a web application assessment, pay attention to:
Account Management
/user/123/profile?id=123/api/users/123
Orders
/order/9821/api/orders/9821
Documents
/document/551/download?file=551
Messages
/message/7321
Support Tickets
/ticket/4102
Invoices
/invoice/9981
Media Files
/media/8821
The specific parameter name does not matter.
What matters is whether the value identifies a protected object and whether the server verifies authorization.
How to Prevent IDOR
The most important rule is simple:
Never trust an object identifier supplied by the client as proof of authorization.
The server must make the authorization decision.
Enforce Object-Level Authorization
Every request for a protected object should verify whether the current user has access.
Conceptually:
Authenticated User ↓Requested Object ↓Authorization Check ↓Allowed / Denied
Do not assume that because a user is authenticated, they can access every object.
OWASP recommends checking authorization for each object involved in a request.
Scope Database Queries to the Current User
One strong design pattern is to retrieve objects through an already-authorized relationship.
Instead of conceptually doing:
find_object(object_id)
prefer a model where the query is constrained by the current user’s permitted resources:
find_object_for_user(current_user, object_id)
This makes it harder for developers to accidentally forget the authorization step.
OWASP gives a similar example in its IDOR prevention guidance, where an object is queried through the current user’s permitted dataset rather than searching the entire collection.
Use Deny-by-Default Authorization
Applications should deny access unless the user has an explicit reason to receive it.
OWASP recommends deny-by-default policies and validating permissions on every request.
This is especially important when new endpoints are added.
Centralize Authorization Logic
Authorization logic scattered throughout controllers and API endpoints is difficult to maintain.
A centralized authorization layer can help ensure that developers consistently apply:
- Ownership rules
- Role requirements
- Tenant restrictions
- Resource permissions
- Administrative privileges
Centralization also makes security testing easier.
Use UUIDs as Defense in Depth
Random identifiers can make enumeration harder.
For example:
/api/invoices/10021
could become something similar to:
/api/invoices/550e8400-e29b-41d4-a716-446655440000
But UUIDs do not fix IDOR by themselves.
If a user obtains a valid UUID belonging to another account and the server accepts it without checking authorization, the vulnerability remains.
Avoid Exposing Identifiers When They Are Not Needed
Some resources can be associated with the authenticated user without requiring the client to provide an identifier.
For example:
GET /api/my-profile
may be preferable to:
GET /api/profile/12345
when the application only needs to return the currently authenticated user’s profile.
OWASP recommends avoiding unnecessary exposure of identifiers where possible.
IDOR Prevention in Multi-Tenant Applications
Multi-tenant applications need particularly strong object-level authorization.
Every resource should have a clear relationship with its tenant.
For example:
Tenant A ↓Project A ↓Invoice A
A request from Tenant B should not be able to retrieve Invoice A simply because it knows the invoice identifier.
A useful authorization model is:
Current User ↓Current Tenant ↓Permitted Resource ↓Requested Action
Each relationship should be validated on the server.
Logging and Monitoring IDOR Attempts
Authorization failures should also be visible to security teams.
Repeated attempts to access different object identifiers may indicate enumeration or authorization probing.
For example:
User A → Object 1001 → AllowedUser A → Object 1002 → DeniedUser A → Object 1003 → DeniedUser A → Object 1004 → Denied...
A high volume of denied object requests may deserve investigation.
OWASP recommends appropriate authorization logging and specifically discusses logging attempts to access objects without the required authority.
Common IDOR Prevention Mistakes
Mistake 1: Relying on Hidden Fields
Developers sometimes assume a hidden HTML field is trustworthy:
<inputtype="hidden"name="user_id"value="123">
Hidden does not mean secure.
A user controls the browser and can modify the request.
Authorization must happen server-side.
Mistake 2: Checking Only Authentication
This is one of the most common mistakes.
The application verifies:
Is the user logged in?
but forgets:
Does the user own this object?
Authentication and authorization are separate security controls.
Mistake 3: Using UUIDs as the Only Defense
Random identifiers make guessing harder but do not replace authorization.
OWASP explicitly recommends treating complex identifiers as defense in depth rather than as a substitute for access control.
Mistake 4: Protecting GET but Not DELETE
A developer may correctly prevent unauthorized reads but forget to protect state-changing operations.
Every sensitive operation needs appropriate authorization.
Mistake 5: Checking Authorization Only in the Frontend
Disabling a button in JavaScript does not provide security.
An attacker can send the HTTP request directly.
Authorization belongs on the server.
IDOR vs Broken Access Control
IDOR is best understood as a specific pattern within the broader category of broken access control.
Broken Access Control covers many failures, including:
- Unauthorized object access
- Privilege escalation
- Missing function-level authorization
- Tenant isolation failures
- Administrative endpoint exposure
IDOR specifically focuses on situations where a user-controlled reference identifies an object and the application fails to enforce authorization for that object.
OWASP currently categorizes IDOR under Broken Access Control, including it in the current A01:2025 category.
IDOR vs Authentication Bypass
These vulnerabilities are also different.
Authentication
Determines:
Who is the user?
Authorization
Determines:
What is the user allowed to access?
IDOR
Is commonly an authorization failure where:
The user can manipulate an object reference to access something they are not authorized to access.
A user can therefore be completely authenticated and still exploit an IDOR vulnerability.
Secure Development Checklist
Before deploying an application, development teams should verify:
- Every protected object has an authorization rule.
- Authorization is enforced server-side.
- Object ownership is checked.
- Tenant boundaries are enforced.
- API endpoints perform object-level authorization.
- GET requests are protected.
- POST, PUT, PATCH, and DELETE operations are protected.
- Hidden form fields are not trusted.
- Client-side restrictions are not treated as security controls.
- UUIDs are treated as defense in depth.
- Database queries are scoped to authorized resources.
- Authorization failures are logged appropriately.
- Multiple-user authorization tests are included in CI/CD.
- Authorization is retested when application functionality changes.
OWASP’s authorization regression guidance recommends automated tests that specifically verify horizontal escalation and tenant-isolation boundaries as applications evolve.
For developers and security professionals who want to strengthen practical application-security knowledge, “https://academy.pentesthint.com/” cyber security training can help connect authorization concepts with real testing workflows.
Frequently Asked Questions
What is Insecure Direct Object Reference (IDOR)?
Insecure Direct Object Reference (IDOR) is an authorization vulnerability where an application uses a user-controlled object reference without properly verifying whether the user is authorized to access that object.
How does an IDOR attack work?
An attacker identifies a request containing an object reference, such as an ID, filename, or UUID. During an authorized security test, the tester changes that reference and checks whether the application improperly returns or modifies another user’s resource.
Is IDOR still relevant in modern applications?
Yes. Modern APIs, SaaS platforms, mobile applications, and multi-tenant systems frequently expose object identifiers. The terminology may differ—especially BOLA in API security—but the underlying authorization problem remains important.
Are UUIDs enough to prevent IDOR?
No. UUIDs make identifiers harder to guess, but they do not replace authorization. If an attacker obtains another user’s UUID and the server does not check ownership or permissions, the resource may still be accessible.
What is the difference between IDOR and BOLA?
IDOR is the traditional term for an object-reference authorization flaw. Broken Object Level Authorization (BOLA) is commonly used in API security for the same general class of object-level authorization failure.
How can developers prevent IDOR vulnerabilities?
Developers should enforce server-side object-level authorization on every relevant request, scope database queries to authorized resources, use deny-by-default policies, enforce tenant isolation, and avoid trusting identifiers supplied by clients.
Can IDOR affect POST and DELETE requests?
Yes. IDOR is not limited to viewing data. An authorization flaw can allow an attacker to modify, delete, export, or otherwise manipulate another user’s object if the application fails to check authorization for that operation.
What is CWE-639?
CWE-639, Authorization Bypass Through User-Controlled Key, is the MITRE weakness classification associated with situations where modifying a key used to identify data can bypass authorization and expose another user’s records. MITRE also lists IDOR, BOLA, and horizontal authorization among its related terms.
External Resources
For a detailed defensive explanation, the OWASP IDOR Prevention Cheat Sheet covers object-level authorization, identifier design, and secure database access patterns.
The OWASP Web Security Testing Guide provides a structured methodology for testing IDOR vulnerabilities.
The MITRE CWE-639 reference provides the formal classification for authorization bypass through user-controlled keys.
Conclusion
Insecure Direct Object Reference is a straightforward vulnerability with potentially serious consequences.
The underlying problem is not simply that an application uses IDs in URLs or API requests. The real issue is that the application fails to verify whether the authenticated user has permission to access the specific object represented by that ID.
Strong IDOR prevention therefore starts with server-side authorization. Every request should be evaluated against the user’s permissions, ownership relationships, tenant boundaries, and requested action.
Random identifiers such as UUIDs can make enumeration more difficult, but they should only be considered an additional layer of defense. They cannot replace object-level authorization.
For penetration testers, IDOR testing should cover more than a single URL parameter. Test object references across URLs, query strings, JSON bodies, APIs, files, and state-changing operations. Use multiple authorized test accounts to verify horizontal and vertical authorization boundaries.
For developers, the safest approach is to make authorization part of the application’s data-access design rather than treating it as an optional check at the edge.
If you’re building practical web application security skills, explore “https://pentesthint.com/” PentestHint for cybersecurity resources and “https://vuln.pentesthint.com/” vulnerability labs for controlled security practice.
