main logo icon

Published on

July 1, 2026

|

11 min read

Why Automated API Scanners Miss BOLA and IDOR: Testing Object-Level and Tenant-Isolation Authorization

Automated API scanners pass on BOLA and IDOR because they cannot infer object ownership, tenant boundaries, or business context. Here is what real object-level authorization testing adds, with defender-framed methodology.

Armaan Pathan

Armaan Pathan

Senior Penetration Tester

Web App Security

Summarize with AI

ChatGPTPerplexityGeminiGrokClaude

TL;DR

Automated API scanners and DAST tools reliably find injection, misconfiguration, and known-class bugs. They miss broken object level authorization (BOLA) and IDOR because a scanner cannot know who owns an object, where one tenant ends and another begins, or which role should reach which endpoint. Those facts live in business context, not in the HTTP response, so a leaked record still returns a clean 200. Real object-level authorization testing closes the gap: provision multiple accounts across tenants, replay one account's object IDs as another, and check horizontal access (peer objects), vertical access (higher-privilege functions, the BFLA case), and property-level writes (mass assignment). BOLA sits at the top of the OWASP API Security Top 10 2023 for exactly this reason. Stingrai's Snipe agent is built to hunt these complex authorization flaws directly.

Automated API scanners miss BOLA and IDOR because a scanner cannot infer who owns an object, where one tenant's data ends and another's begins, or which role is supposed to reach a given endpoint. Those facts live in your application's business logic, not in the HTTP response, so a request that quietly returns another customer's record still comes back as a clean 200. The scanner sees a well-formed request and a valid response, marks it passing, and moves on. Manual object-level authorization testing closes that gap by comparing what different accounts and roles are actually allowed to do, and it is the single highest-value thing a real API pentest adds on top of a scanner report.

Broken Object Level Authorization sits at number one on the OWASP API Security Top 10 2023 (API1:2023). It is the most common and one of the most damaging API flaws precisely because it is invisible to the tools most teams run first. This post defines BOLA and IDOR clearly, explains why scanners structurally cannot catch them, and walks through the defender-framed test methodology, using synthetic examples you can adapt to your own application.

The short answer

A scanner verifies that a request works. Authorization is about who the request is for. BOLA, IDOR, broken function level authorization (BFLA), and mass assignment are all failures of "who is allowed to do this," and a scanner has no model of your users, tenants, or roles. It cannot tell that account B just read account A's invoice, because both requests are technically valid and both return 200. Catching the flaw requires a tester (human or a purpose-built agent) that holds two or more accounts, knows which objects each one legitimately owns, and checks every boundary between them.

Bola Idor Bfla Mass Assignment Comparison

BOLA vs IDOR: same bug, two names

BOLA and IDOR describe the same underlying failure: an object is exposed through a client-supplied identifier, and the server hands it over without checking that the caller is allowed to have it. "IDOR" (insecure direct object reference) is the classic web-application name. "BOLA" is the API-era name OWASP standardized in its API Security Top 10. If you read a report that lists one and not the other, you are still looking at the same class of flaw.

OWASP defines object level authorization as "an access control mechanism that is usually implemented at the code level to validate that a user can only access the objects that they should have permissions to access." The vulnerability is prevalent because API servers typically do not track full client state; they trust the object ID the client sends, whether that is a sequential integer, a UUID, or a string. Change the ID, and if the ownership check is missing, you get someone else's object.

Here is the shape of it, using synthetic values only:

Codejavascript
1GET /api/v1/invoices/1042
2Authorization: Bearer <token for account A>
3-> 200 OK   (A owns invoice 1042: correct)
4
5GET /api/v1/invoices/1042
6Authorization: Bearer <token for account B>
7-> 200 OK   (B does not own 1042: this is the bug)

The second response should be a 403 or a 404. When it returns 200 with A's data, you have BOLA. Note what a scanner sees in both cases: a valid request and a 200 response. Nothing in the HTTP exchange tells the scanner that 1042 belongs to A and not B. That knowledge only exists if the tester provisioned both accounts and recorded which one owns the object.

Two neighboring flaws round out the authorization picture, and both are equally opaque to scanners:

  • Broken Function Level Authorization (BFLA), API5:2023, is the vertical case: a lower-privilege user reaches a function meant for a higher role. Think of a standard user calling POST /api/v1/admin/users and having it succeed. The scanner cannot tell which role should reach which route, so it never tries the request as the wrong role.

  • Mass assignment, folded into Broken Object Property Level Authorization (API3:2023), is the property-level case: a user writes a field they should not control, such as "role": "admin" or "balance": 0, by adding it to an otherwise legitimate request body. OWASP describes API3:2023 as the endpoint exposing or allowing modification of "properties of an object that are considered sensitive and should not be read" or written by the user. A scanner does not know which fields are privileged, so it does not know to inject them.

Flaw

OWASP ID

What it is

Why a scanner misses it

BOLA

API1:2023

Read or change another owner's object by swapping an object ID

No model of who owns the object

IDOR

classic name

The web-app label for the same object-level failure

A 200 looks identical whether or not it should be yours

BFLA

API5:2023

Reach a function above your role

No model of which role should reach which route

Mass assignment

API3:2023 (BOPLA)

Write a privileged property via an extra field

No model of which fields are privileged

Why scanners cannot infer ownership

Automated scanners are excellent at what they are built for: fuzzing inputs, spotting injection, flagging missing security headers, catching known misconfigurations. Those are all things you can detect from the request and response alone. Authorization is different in kind. The correct answer to "should this account see invoice 1042?" is not in the response at all; it is a fact about your data model.

Why Scanners Miss Context Gap

A scanner can confirm the request is well-formed, that the response is a 200, that the body validates against the schema, and that no error string appears. It cannot know which account owns object 1042, where tenant A ends and tenant B begins, which role should be allowed to reach /admin, or which fields in a payload are privileged. Every one of those is business context. To test authorization, you have to supply that context deliberately: multiple accounts in multiple tenants and roles, and a map of what each one is entitled to.

This is also why a "clean" scanner report is so misleading on this specific class of bug. The absence of BOLA findings in a scanner report is not evidence that BOLA is absent. It is evidence that the tool was never able to look.

Testing object-level and tenant-isolation authorization

Real authorization testing means moving along two axes at once: whose object, and which role. That gives you four quadrants, and only one of them should ever succeed.

Horizontal Vertical Authorization Matrix
  • Own object, own role should return 200. This is the baseline that proves the feature works.

  • Peer's object, own role is the horizontal test. Account B requesting account A's object must be denied. This is the pure BOLA / IDOR case.

  • Own scope, higher-privilege action is the vertical test. A standard user invoking an admin function must be denied. This is the BFLA case.

  • Cross-boundary object and function together must also be denied. Both axes fail at once, which is common in multi-tenant SaaS where an object ID and a role check both matter.

The multi-account object-ID test

The reliable way to prove object-level and tenant-isolation controls hold is the multi-account test. It is a defender-side method: you run it against your own application, using accounts you control, to confirm that a real cross-tenant attempt is blocked.

Multi Account Object Id Test Flow
  1. Provision at least two accounts in separate tenants, plus one privileged account. You need a real ownership boundary to test, not two users in the same workspace.

  2. Capture the object IDs that account A legitimately owns. As tenant A, walk the application normally and record the IDs it creates and reads: invoices, documents, projects, whatever your objects are.

  3. Replay A's exact requests using B's session. Same endpoints, same object IDs, B's token. Every one of these must return 403 or 404, never A's data. If any returns A's object, that is a confirmed BOLA finding.

  4. Flip role and field. As tenant B, try the admin routes to test BFLA, and add privileged fields (role, isAdmin, tenantId, price fields) to write requests to test mass assignment. A correct system rejects or ignores every one.

A few practices make this rigorous rather than cursory. Test predictable and unpredictable IDs both: OWASP notes that sequential integers are the easiest to abuse, but UUIDs are not a control by themselves, only obscurity. Cover every verb, not just GET; a system can gate reads and leak writes, or vice versa. Check nested and indirect references, where an object ID appears inside a body or a second-order lookup rather than in the path. And confirm the negative direction too: run A against B's objects, not only B against A's, because tenant isolation is not always symmetric.

Where an autonomous agent fits

The multi-account method is thorough, but it is also combinatorial. A real API has dozens of endpoints, several roles, and many object types, and every pairing is a test. Doing it exhaustively by hand on a large surface is slow, which is exactly where an agent trained on this class of bug earns its place.

Stingrai's Snipe is an autonomous agent for web application penetration testing built specifically to hunt the complex, high-impact classes that generic scanners miss: IDOR and BOLA, business logic flaws, and broken authorization. It is custom-trained on more than 6,000 HackerOne Hacktivity disclosure reports and on skills distilled from Stingrai's human pentesters' methodology, so it encodes how senior testers actually reason about ownership and tenant boundaries rather than just matching known signatures. Snipe works black-box, driving multi-account request replays the way the method above describes, and white-box, reading application source to see where an ownership check is missing before a request is ever sent. When it finds an issue it can open an AutoFix pull request, and it can run as a PR-gating check so a missing authorization check is caught before the code merges.

The point is not to replace the human tester. Senior pentesters validate and extend what Snipe finds, chase the business-logic edge cases that need product knowledge, and confirm impact. The agent makes the combinatorial part fast and repeatable so that the object-level and tenant-isolation coverage is actually complete, not sampled.

What this means for defenders

  • Treat a clean scanner report as a starting point, not a clearance. For BOLA, IDOR, BFLA, and mass assignment, the absence of findings usually means the tool could not look, not that the flaw is absent. Ask specifically whether object-level and tenant-isolation authorization was tested.

  • Enforce authorization at the object, not the route. OWASP's core recommendation is to check, for every function that accesses a record from a client-supplied ID, that the current user is allowed that specific object. Route-level middleware is not enough.

  • Build the multi-account test into CI. A small suite that replays one tenant's object IDs as another and asserts 403 catches regressions the moment an ownership check is dropped. Consider a continuous testing model so coverage keeps pace with new endpoints.

  • Include authorization in every application pentest scope. When you commission penetration testing, confirm the statement of work covers horizontal and vertical access control and multi-tenant isolation explicitly, not just injection and configuration.

  • Shift the check left with white-box review. Finding a missing ownership check in source is cheaper than finding it in production. Static review and PR-gating catch the flaw before it ships.

Frequently Asked Questions

Why do automated API scanners miss BOLA and IDOR vulnerabilities?

Scanners miss BOLA and IDOR because authorization is a fact about your data model, not something visible in the HTTP exchange. A scanner can confirm a request is well-formed and returns a 200, but it cannot know who is supposed to own the object being requested. When account B successfully reads account A's record, the response looks identical to a legitimate 200, so the scanner marks it passing. Only a test that holds multiple accounts and knows which one owns each object can catch the leak.

What is the difference between BOLA and IDOR?

They are two names for the same flaw. IDOR (insecure direct object reference) is the classic web-application term for exposing an object through a client-supplied ID without an ownership check. BOLA (Broken Object Level Authorization) is the name OWASP standardized in its API Security Top 10 2023, where it ranks as API1:2023, the top API risk. If a report lists one and not the other, it is still the same object-level access-control failure.

What does manual object-level authorization testing add over a scanner?

It adds business context. A tester provisions multiple accounts across tenants and roles, records which objects each one legitimately owns, then deliberately tries to cross those boundaries: replaying one account's object IDs as another, invoking higher-privilege functions as a lower-privilege user, and injecting privileged fields into writes. None of that is possible without a model of who is entitled to what, which is exactly what a scanner lacks.

How do you test for broken object level authorization?

Provision at least two accounts in separate tenants plus one privileged account. As the first account, capture the object IDs it legitimately owns. Then replay those exact requests using the second account's session across every verb, not just GET. Every cross-account request must return 403 or 404, never the first account's data. Any request that returns another owner's object is a confirmed BOLA finding.

What is tenant isolation testing?

Tenant isolation testing verifies that data belonging to one customer (tenant) in a multi-tenant application cannot be reached by another. It is the multi-tenant form of object-level authorization testing: you confirm that tenant B cannot read, modify, or delete tenant A's objects through any endpoint, and you test the boundary in both directions because isolation is not always symmetric.

What is a mass assignment vulnerability?

Mass assignment is a property-level authorization flaw where an API lets a user set fields they should not control by adding them to a legitimate request body, for example injecting "role": "admin" into a profile update. OWASP folds it into Broken Object Property Level Authorization (API3:2023). Scanners miss it because they do not know which fields are privileged.

What is BFLA and how is it different from BOLA?

BFLA (Broken Function Level Authorization, API5:2023) is the vertical case: a user reaches a function above their role, such as a standard user calling an admin endpoint. BOLA is the horizontal case: a user reaches another owner's object at their own privilege level. Both are authorization failures, but one is about role, the other about ownership. A complete test covers both axes.

Can an AI tool find business logic and authorization flaws?

Generic AI scanners tend to cap out at known-class bugs and miss business logic and authorization, which is the well-documented gap in the market. Stingrai built its Snipe agent specifically to close that gap. Snipe is trained on more than 6,000 HackerOne disclosure reports and on senior pentester methodology, and it hunts IDOR, BOLA, and broken authorization directly, black-box and white-box, then opens AutoFix pull requests and can gate merges.

References

  1. OWASP. API1:2023 Broken Object Level Authorization. OWASP API Security Top 10 2023. https://owasp.org/API-Security/editions/2023/en/0xa1-broken-object-level-authorization/. Defines object-level authorization, why it is the top API risk, and the testing and prevention approach.

  2. OWASP. API3:2023 Broken Object Property Level Authorization. OWASP API Security Top 10 2023. https://owasp.org/API-Security/editions/2023/en/0xa3-broken-object-property-level-authorization/. Consolidates mass assignment and excessive data exposure into property-level authorization.

  3. OWASP. API5:2023 Broken Function Level Authorization. OWASP API Security Top 10 2023. https://owasp.org/API-Security/editions/2023/en/0xa5-broken-function-level-authorization/. Describes vertical access-control failures across role hierarchies.

  4. OWASP. API Security Top 10 2023. https://owasp.org/API-Security/editions/2023/en/0x11-t10/. The full 2023 ranking of the most critical API security risks.

0 views

0

X

Related reading

CI/CD Pipeline Penetration Testing: What a Build-Chain Test Scopes That an App Pentest Misses
Web App Security

CI/CD Pipeline Penetration Testing: What a Build-Chain Test Scopes That an App Pentest Misses

What a CI/CD pipeline penetration test covers and how it differs from an app pentest: secrets, OIDC, runners, action supply chain, deploy tokens.

11 min read

Do AI-Coded Apps Need a Penetration Test? What Copilot and Cursor Output Actually Breaks
Web App SecurityLLM Security

Do AI-Coded Apps Need a Penetration Test? What Copilot and Cursor Output Actually Breaks

Why Copilot and Cursor output needs adversarial testing, the exact bug classes AI code breaks on, and a pentest plus PR-gating workflow to fix it.

11 min read

Your RAG Vector Store Is an Unauthenticated Asset: Testing Knowledge-Base Access Control and Ingestion
LLM SecurityWeb App Security

Your RAG Vector Store Is an Unauthenticated Asset: Testing Knowledge-Base Access Control and Ingestion

Test your RAG pipeline before attackers do. How to check vector store access control, tenant isolation, and ingestion authz, plus what RAG poisoning takes.

12 min read

Contents

X