Authorization, not injection, is what breaks most modern APIs. The two flaw classes that do the damage — BOLA and BFLA — are invisible to a scanner, because a scanner has no concept of who should be allowed to do what. Here is the difference between them, why pattern matching cannot find either, and how to actually test for both.
Planck Defense · Offensive Security Team · August 28, 2026 · 7 min read
Look at almost any serious API breach of the last few years and you will find the same root cause: not a clever injection payload, but a missing authorization check. Someone requested an object that was not theirs, or called a function they should never have reached, and the server handed it over. These are the two classes at the top of the OWASP API Security Top 10 — BOLA at number one and BFLA at number five — and together they account for the majority of real-world API compromise.
They are also the flaws your scanner will never report. Understanding why starts with knowing exactly what each one is.
BOLA is a failure to check that the user asking for an object is allowed to have that specific object. APIs expose objects by identifier — /orders/124, /users/89/profile, /documents/abc-123 — and the vulnerability is simple: the endpoint authenticates you (it knows you are a logged-in user) but never verifies that order 124 belongs to you before returning it.
So an attacker logs in with their own account, sees a request for GET /orders/124, and simply changes the number: GET /orders/125, 126, 127. If the server returns each one, they can walk the entire order table — other customers' addresses, amounts, and items — without ever touching an admin function. If you have heard this called IDOR (insecure direct object reference), it is the same bug; OWASP renamed it BOLA for the API context. Identifiers do not have to be sequential integers, either. UUIDs assumed to be unguessable, references buried in a request body, and IDs resolved through nested GraphQL fields are all BOLA surface.
BFLA is a failure to check that the user is allowed to perform that action at all. Where BOLA is about data you should not see, BFLA is about functions you should not be able to call. A standard user finds the admin routes — DELETE /users/89, POST /admin/refunds, PUT /accounts/settings/global — and simply calls them with their ordinary session token. If the server executes the request because it only checked that you are logged in, not which role you hold, that is BFLA.
It often hides behind the client. The admin button is not rendered in your UI, so the assumption is that you cannot reach the function — but the API endpoint is still live, and nothing stops you from calling it directly. Switching an HTTP method on the same path (GET to DELETE), guessing an undocumented admin route, or invoking a gRPC service method the client was never meant to expose are all ways BFLA shows up.
The quickest way to keep them straight: BOLA crosses between accounts at the same level; BFLA crosses between levels. BOLA is a regular user reaching another regular user's data. BFLA is a regular user reaching an administrator's powers.
| Dimension | BOLA | BFLA |
|---|---|---|
| OWASP API rank | API1 (2023) | API5 (2023) |
| What fails | Object ownership check | Role / privilege check |
| Attacker gains | Another user's data | A function above their role |
| Boundary crossed | Between peer accounts | Between privilege levels |
| Classic example | GET /orders/{other_id} | DELETE /users/{id} as a normal user |
| Also known as | IDOR | Privilege escalation, forced browsing |
| How to catch it | Replay one account's request as another | Replay a low-privilege token against privileged routes |
Some findings are both at once: an endpoint that is both admin-only and object-scoped can fail on either axis, which is why real testing checks each dimension separately on every operation.
A vulnerability scanner or DAST tool works by firing payloads at inputs and matching responses against a library of signatures. That model is fundamentally blind to authorization, for one reason: authorization is relative. There is nothing wrong with the response to GET /orders/124 in isolation — it is a perfectly valid 200 with a valid order. Whether it is a vulnerability depends entirely on who asked. A scanner sees one request, one response, one identity. It cannot express the question that defines BOLA and BFLA: “should this user be allowed to do this?”
To answer that, you need at least two accounts and a way to compare them — to take a request that is legitimate for user A and replay it as user B, then check whether the server wrongly allows it. That is a stateful, identity-aware, multi-account exercise. It is exactly the shape of testing a signature engine cannot do, which is why these flaws sail straight through automated scans and land in production.
The method is conceptually simple and mechanically demanding. You authenticate as two or more user types — at minimum two peer accounts (for BOLA) and one low-privilege plus one high-privilege account (for BFLA). Then, for every operation the API exposes:
Doing this by hand across a real API — dozens or hundreds of operations, each with multiple parameters, times several role pairings — is enormous, repetitive work, which is why it so often gets sampled rather than done completely. This is where an agentic API penetration test fits the problem exactly. You provide one bearer token per user type; the agent parses your OpenAPI spec, enumerates every operation, and replays one role's requests as another across the whole surface. Because it is an agentic pentester rather than a scanner, it does not stop at “this looks off” — it confirms the cross-account access actually happened and reports it with the exact request and response that prove it, rated with a CVSS v3.1 vector.
Authorization is the part of API security that pattern matching cannot reach and that manual testing rarely covers exhaustively. Testing it well means treating every endpoint as a question about identity, and answering that question with more than one account. Anything less leaves the most common path into your data untested.
This is the Operator console running exactly the test described above: cross-account BOLA on object identifiers, then BFLA on admin-only functions called with a low-privilege token. Illustrative demo against api.example.com — the requests, sessions, and confirmations are what a real run streams.
BOLA (broken object level authorization) is about data: a user accesses another user's object, such as requesting GET /orders/124 when order 124 belongs to someone else. BFLA (broken function level authorization) is about actions: a user invokes a function or role they should not reach, such as a standard user calling an admin-only endpoint. BOLA crosses the boundary between accounts at the same privilege level; BFLA crosses the boundary between privilege levels.
Largely yes. IDOR (insecure direct object reference) is the older name for the same class of bug. OWASP formalized it as BOLA, the number one risk in the API Security Top 10. BOLA is the term used for APIs, where object identifiers in the URL path or request body are the most common way the flaw appears.
A scanner tests one request at a time against a signature and has no concept of identity or roles. BOLA and BFLA are only visible when you compare what one user can do against what another user should be allowed to do, which requires at least two authenticated accounts and replaying one role's requests as another. Pattern matching cannot express that.
You authenticate as two or more user types, then for every endpoint that accepts an object identifier or exposes a privileged function, you replay one role's request as another and check whether the response leaks data or performs the action. An agentic pentester does this across every documented operation and reproduces each finding with the exact cross-account request and response.
Spec-driven testing of every operation, with cross-account BOLA and BFLA at its core.
Read → BlogWhy a signature scanner and a reasoning agent are different tools doing different jobs.
Read → BlogInside proof-based validation: why every finding is reproduced before it reaches you.
Read →Give Operator your spec and a token per role. It will replay one role as another across every operation, and prove what it finds.