#1
BOLA/IDOR is the top-ranked vulnerability in the OWASP API Security Top 10 (2023 edition), present in the majority of APIs not explicitly designed with object-level authorization
5 scenarios
that cover the majority of BOLA attack surface: read access to another user's object, write access, delete access, cross-tenant access in multi-tenant applications, and horizontal privilege escalation via role ID manipulation
40%
of HackerOne API-related vulnerability reports cite IDOR/BOLA as the root cause -- the highest single category of API vulnerability in public bug bounty programs
Critical
impact classification applies when BOLA enables cross-tenant data access, bulk enumeration of all users' records, or write/delete access to other users' sensitive resources

SponsoredRetool

Retool's new app builder is where AI-generated code ships safely

Building apps with AI is easy. Getting them to production safely is another story.

Start building for free today

BOLA is the most prevalent API security vulnerability category because it does not require a complex exploit chain. It requires only that the API trusts the client to send a correct object identifier, and checks authentication (is this user logged in?) but not authorization (is this user authorized to access this specific object?). In multi-tenant SaaS applications, the gap between authentication and object-level authorization is a design decision that was never made explicit -- and that produces cross-tenant access that the application team did not intend.

Testing for BOLA systematically requires more than simply changing a numeric ID in a request and observing whether the response changes. It requires understanding the data model, mapping the object identifiers used in each API endpoint, testing read, write, and delete operations across multiple user contexts, and evaluating whether identifiers are guessable or enumerable.

This guide covers the five test scenarios that surface the majority of BOLA findings, the tooling setup for systematic testing, the impact framework that separates findings worth escalating immediately from findings worth documenting in the backlog, and the code-level fix that prevents BOLA at the authorization layer.

Understanding the BOLA Attack Surface Before Testing

Before running any test, map the object identifiers used in the API. Object identifiers are the values in API requests that reference specific resources: user IDs in URL path parameters, order numbers in query strings, document IDs in request bodies, session tokens that embed user context. Each identifier type has a different BOLA risk profile.

Numeric sequential IDs (user_id=1234, order_id=5678) are the highest risk because they are trivially enumerable. An attacker who knows their own ID can systematically iterate through adjacent IDs to access other users' resources.

UUIDs and GUIDs reduce but do not eliminate BOLA risk. A UUID is not guessable, but if the API leaks other users' UUIDs in any response (for example, including a creator's user_id in a public-facing object response), those UUIDs can be used for BOLA testing.

Opaque tokens or hashed IDs (base64-encoded values, MD5 hashes of user attributes) are sometimes mistakenly assumed to provide security by obscurity. They reduce enumerability but do not eliminate BOLA if the identifier can be obtained through a related API call.

Map the identifier types by reviewing: the API's OpenAPI specification (if available), every URL path pattern in the application, request bodies that include ID fields, and responses that include references to other objects' IDs. This map guides the test plan and ensures no identifier type is missed.

The Five Test Scenarios That Cover Most of the BOLA Surface

Scenario 1: Read access to another user's object. With two test accounts (User A and User B), perform the API call to read User A's object (order, profile, document, message) using User B's authenticated session. Replace User A's object identifier in the request with a valid identifier from User A's data. If the response returns User A's data without an authorization error, the endpoint is vulnerable to BOLA for read access.

Scenario 2: Write access to another user's object. Using User B's session, make a PUT, PATCH, or POST request to modify User A's object. The most impactful write BOLA: modifying another user's email address (account takeover), adding items to another user's cart, modifying another user's payment information, or updating permissions or roles that affect another user's access.

Scenario 3: Delete access to another user's object. Using User B's session, issue a DELETE request for User A's resource ID. Successful deletion is a high-impact finding even if the data itself is not sensitive, because it creates a denial-of-service capability against any user's resources.

Scenario 4: Cross-tenant access in multi-tenant applications. This is the highest-severity BOLA variant. Create accounts in two different tenants (organizations, teams, workspaces). Using Tenant B's credentials, attempt to access Tenant A's resources by substituting Tenant A's object IDs. If the application does not enforce tenant isolation at the database query level, this produces cross-tenant data access -- a finding that typically requires immediate escalation and hotfix.

Scenario 5: Horizontal privilege escalation via role or permission ID. Some APIs allow users to specify a role_id or permission_id in requests. Test whether a standard user can escalate to an admin role by substituting an admin role's ID in the relevant request. This is BOLA applied to access control objects rather than data objects.

Free daily briefing

Briefings like this, every morning before 9am.

Threat intel, active CVEs, and campaign alerts, distilled for practitioners. 50,000+ subscribers. No noise.

Testing Setup: Burp Suite for Systematic Authorization Testing

Manual testing of all five scenarios across all API endpoints is too slow for comprehensive coverage. Burp Suite's Repeater and Intruder, combined with the AuthMatrix or AuthZ extension, provide systematic coverage.

Session setup. In Burp Suite, configure two browser sessions with two distinct user accounts. Use Burp's "Match and Replace" feature or the Authorize extension to automatically test each request captured in Proxy with both sessions -- the session that originally made the request (expected to succeed) and the second user's session (expected to fail). The Authorize extension colors requests red when the second session receives the same HTTP 200 response as the original, indicating a likely BOLA.

Scoping the test to object endpoints. Filter the captured traffic to endpoint patterns that include object identifiers in the path (e.g., /api/v1/orders/{id}, /api/v1/users/{id}/settings). In Burp's Target > Site map, filter by path patterns containing ID segments. Focus testing on these endpoints.

Intruder for ID enumeration testing. For endpoints using numeric sequential IDs: configure Burp Intruder with the numeric ID as the payload position and a sequential number list ranging from your User A's known IDs to adjacent IDs (User A's ID minus 10 to plus 10, for example). Use the "Cluster Bomb" or "Sniper" attack type. Analyze the response length -- a response with content significantly longer than the "not found" or "forbidden" response indicates successful access to another user's resource.

GraphQL-specific testing. GraphQL APIs require testing object identifiers in query variables as well as in the query field arguments. Test introspection (if enabled) to understand the full object graph, then construct queries that reference objects by ID. The same five scenarios apply, but the access path may be through query arguments rather than URL path parameters.

Impact Classification: Separating Critical Findings from Informational

Not all BOLA findings have the same impact. The classification framework determines escalation path and remediation priority.

Critical (immediate escalation, hotfix required):

  • Cross-tenant data access in a multi-tenant application (accessing another organization's records)
  • Read access to another user's credentials, payment data, PII, or health data
  • Write or delete access that enables account takeover (modifying email, password reset token, or authentication method)
  • Bulk enumeration capability that allows exfiltrating all users' records (sequential IDs that allow iterating through the entire user base)

High (expedited remediation, within 7 days):

  • Read access to another user's private content that does not involve regulated data
  • Write access to non-sensitive fields of another user's records
  • Delete access to another user's resources (denial of service capability)

Medium (standard vulnerability remediation SLA):

  • Read access to other users' non-sensitive metadata (usernames, public profile fields) that are not intended to be accessible but do not expose sensitive information
  • BOLA in administrative endpoints that require elevated authentication to reach (attacker must first escalate to admin before the BOLA is reachable)

Low/Informational:

  • BOLA findings where the object identifier is a UUID that is not leaked elsewhere in the API and cannot be enumerated without prior knowledge
  • Findings in deprecated API versions that are disabled for external traffic

The Code-Level Fix: Authorization at the Query Layer

BOLA is fixed at the data access layer, not the presentation layer. Adding an authorization check after fetching the data is less secure than filtering at the query level.

The wrong pattern (fetch then check):

const order = await db.orders.findById(req.params.id);
if (order.userId !== req.user.id) {
  return res.status(403).json({ error: 'Forbidden' });
}
return res.json(order);

This pattern still fetches the data before checking authorization. Timing attacks and error message differences can sometimes leak information about whether the record exists. It is also more error-prone -- a developer forgetting the authorization check means the endpoint is fully exposed.

The correct pattern (filter at query):

const order = await db.orders.findOne({
  id: req.params.id,
  userId: req.user.id  // enforced at query level
});
if (!order) {
  return res.status(404).json({ error: 'Not found' });
}
return res.json(order);

By including the authenticated user's ID as a filter condition in the query, the database never returns records belonging to other users regardless of what ID is passed in the request. The response is identical for a non-existent record and a record belonging to another user, which prevents information leakage about the existence of the resource.

For multi-tenant applications, apply the same pattern at the tenant level: every query that touches tenant-scoped data must include the authenticated tenant's ID as a filter condition. This should be enforced at the data access layer (ORM, repository class, or database stored procedure) rather than relying on individual endpoint implementations to include the filter.

Documenting and Tracking BOLA Findings Across an API Surface

An API surface with dozens of endpoints requires systematic finding documentation to ensure all vulnerable endpoints are remediated, not just the ones that surfaced in the initial test.

Endpoint authorization matrix. Create a spreadsheet or security ticket board with one row per API endpoint (method + path). Columns: object identifier type, authorization check present (yes/no/not applicable), test status (not tested, tested clean, BOLA confirmed), impact classification, remediation status. This matrix provides at-a-glance coverage and prevents individual BOLA findings from being fixed in isolation while similar endpoints remain vulnerable.

Root cause categorization. Group BOLA findings by root cause rather than by endpoint. In most applications, BOLA findings cluster around specific code patterns: a shared data access module that does not enforce user scoping, a specific ORM query pattern, or a code generation template that does not include authorization filtering. Fixing the root cause pattern eliminates all endpoints that share it, rather than requiring individual fixes per endpoint.

Regression test for remediated endpoints. After BOLA remediation, add automated authorization tests to the API test suite that verify the fix. The test: create two authenticated user sessions, perform the previously-BOLA-vulnerable request with User B's session against User A's object ID, assert that the response is 403 or 404. These tests run on every deployment and prevent the vulnerability from reintroduced through refactoring.

The bottom line

BOLA is the top-ranked API vulnerability category because the authorization gap it exploits -- authentication without object-level authorization -- is a design decision that was never explicitly made rather than a coding mistake that is easy to spot in code review. Systematic testing requires mapping all object identifier types, running all five scenarios (read, write, delete, cross-tenant, role escalation) across all endpoints, and using Burp Suite Authorize or equivalent tooling to automate the dual-session test. Impact classification determines escalation urgency: cross-tenant access and bulk enumeration capabilities are critical and require immediate hotfix; non-sensitive read access is medium. The fix is authorizing at the query layer with the authenticated user's context as a filter condition, not checking after the fact. Track findings in an endpoint authorization matrix and add regression tests to prevent reintroduction.

Frequently asked questions

What is the difference between BOLA and IDOR?

BOLA (Broken Object Level Authorization) and IDOR (Insecure Direct Object Reference) describe the same vulnerability class from different naming conventions. IDOR is the older term from the OWASP Top 10 Web Application Security Risks list, referring to when a direct reference to an internal object (like a database ID in a URL) is exposed without authorization validation. BOLA is the OWASP API Security Top 10 terminology, which emphasizes the authorization failure (not the reference itself) as the vulnerability. In practice, the terms are used interchangeably.

How do I test for BOLA vulnerabilities in an API?

The five-scenario methodology covers most of the BOLA attack surface: test read access to another user's object (substitute another user's ID in the request using your session), write access (modify another user's object), delete access, cross-tenant access in multi-tenant apps, and role ID manipulation for privilege escalation. For tooling: use Burp Suite's Authorize extension to automatically test each captured request with a second user's session, flagging responses where the second session receives the same HTTP 200 as the original. Map all object identifier types (numeric IDs, UUIDs, hashed values) before testing -- each type has different risk and enumerability characteristics.

What makes a BOLA finding critical versus medium severity?

Critical BOLA: cross-tenant data access in a multi-tenant application (accessing another organization's records), read access to credentials, payment data, PII, or health data, write access that enables account takeover (modifying email or authentication methods), or bulk enumeration capability allowing exfiltration of all users' records. High: read access to private non-regulated content, write access to non-sensitive fields, delete access (denial of service capability). Medium: access to non-sensitive metadata not intended to be public, BOLA in endpoints requiring prior privilege escalation. Low: findings where the object identifier is a non-enumerable UUID not leaked elsewhere in the API.

How do I fix a BOLA vulnerability in my API code?

Fix BOLA at the database query layer, not the presentation layer. The wrong pattern: fetch the record by ID, then check whether it belongs to the authenticated user -- this still fetches the record and is error-prone. The correct pattern: include the authenticated user's ID as a filter condition in the database query, so the query returns nothing if the record belongs to another user. For multi-tenant applications, include the tenant ID as a filter condition on every query against tenant-scoped data, enforced at the data access layer (ORM, repository class) rather than per-endpoint.

Can UUIDs prevent BOLA vulnerabilities?

UUIDs reduce BOLA risk by making object identifiers non-enumerable (a UUID cannot be guessed by incrementing from a known ID), but they do not eliminate it. If the API leaks other users' UUIDs in any response -- for example, including a creator's user_id in a public-facing object response, or returning user IDs in a list endpoint -- those UUIDs can be used directly in BOLA attacks. The authorization check at the query layer is required regardless of whether the identifier type is a sequential integer or a UUID.

What is cross-tenant BOLA and why is it critical?

Cross-tenant BOLA occurs in multi-tenant SaaS applications when a user in one tenant (organization, workspace, account) can access resources belonging to a different tenant by substituting the other tenant's object IDs. It is the highest-severity BOLA variant because it violates the fundamental data isolation guarantee that multi-tenant SaaS products rely on -- tenant A's data must never be accessible to tenant B. Cross-tenant BOLA often triggers breach notification obligations if sensitive data is involved, because records from one organization were accessed by an unauthorized party from a different organization.

How do I prevent BOLA from being reintroduced after remediation?

Add automated authorization regression tests to the API test suite that run on every deployment. The test structure: create two authenticated user sessions for distinct users (or tenants, for cross-tenant testing), perform the previously-vulnerable request with User B's session targeting User A's resource ID, and assert that the response status is 403 or 404 -- not 200 with User A's data. Fix the root cause code pattern (the data access module that does not enforce user scoping) rather than patching individual endpoints, so all endpoints sharing the pattern are protected by the same fix.

Sources & references

  1. OWASP API Security Top 10: API1 BOLA
  2. PortSwigger: IDOR Testing Methodology
  3. OWASP Testing Guide: Testing for Insecure Direct Object References
  4. HackerOne: Top IDOR Reports
  5. Akamai: State of the Internet Security Report -- API and Web Attack

Free resources

25
Free download

Critical CVE Reference Card 2025–2026

25 actively exploited vulnerabilities with CVSS scores, exploit status, and patch availability. Print it, pin it, share it with your SOC team.

No spam. Unsubscribe anytime.

Free download

Ransomware Incident Response Playbook

Step-by-step 24-hour IR checklist covering detection, containment, eradication, and recovery. Built for SOC teams, IR leads, and CISOs.

No spam. Unsubscribe anytime.

Free newsletter

Get threat intel before your inbox does.

50,000+ security professionals read Decryption Digest for early warnings on zero-days, ransomware, and nation-state campaigns. Free, daily, no spam.

Unsubscribe anytime. We never sell your data.

Eric Bang
Author

Founder & Cybersecurity Evangelist, Decryption Digest

Cybersecurity professional with expertise in threat intelligence, vulnerability research, and enterprise security. Covers zero-days, ransomware, and nation-state operations for 50,000+ security professionals every morning.

Black Hat Giveaway

Win a $2,495 Black Hat pass.

Full-access to Black Hat USA 2026 in Las Vegas. Subscribe free to enter.

Joins Decryption Digest daily briefing. Unsubscribe anytime.

Giveaway: Black Hat USA 2026 Full-Access Pass ($2,495 value)

Details →
Daily Briefing

Subscribe to enter the giveaway

Every subscriber is automatically entered. You also get daily threat intel every morning: zero-days, ransomware, and nation-state campaigns. Free. No spam.

Already subscribed? You're already entered.

Giveaway

Win a $2,495 Black Hat USA 2026 pass.