A bola vulnerability, short for broken object level authorization, happens when an API checks that a user is logged in but never verifies that the specific object they're requesting actually belongs to them — so changing an ID in a request URL or request body, like /api/orders/1042 to /api/orders/1043, returns another user's data with no error, no alert, and no exploit code beyond editing a number. It has topped the OWASP API Security Top 10 for years running, and the reason it stays there isn't that the fix is technically hard; it's that the bug produces a completely normal-looking response, which makes it one of the hardest vulnerability classes for automated tools to find without specifically testing for it.
Why is BOLA so common in real APIs?
Most authentication frameworks handle the "is this a valid, logged-in user" question well by default, so developers get a strong sense that access control is handled. Authorization — "is this specific user allowed to access this specific object" — is a separate question that has to be explicitly checked in every endpoint that accepts an object identifier, and it's exactly the kind of check that's easy to add in the first version of an endpoint and easy to forget in the fifth, sixth, and tenth endpoints added later by different developers under deadline pressure. APIs are particularly exposed to this because they tend to have many more object-accessing endpoints than a traditional web application, each one a fresh opportunity to skip the ownership check, and API responses returning structured JSON rather than rendered HTML make it trivially easy for an attacker to notice when the returned object doesn't match what they expected — and to script an automated sweep across a whole range of IDs once they've found one.
What does exploiting a BOLA vulnerability actually look like?
The most common pattern is straightforward ID enumeration: an authenticated attacker sends the same request repeatedly with sequential or incrementing object identifiers and records which ones return data belonging to someone else. Because the request looks completely legitimate — a valid session token, a normal API call, just a different number in the path — this rarely triggers any anomaly detection, and it doesn't require any injection payload, malformed input, or unusual traffic pattern that a web application firewall would flag. This is precisely why a bola vulnerability is such a favorite in real-world API breaches: it requires no special tooling, just a valid account and the willingness to try a different ID, which is a dramatically lower bar than most other exploitation techniques.
How do teams actually find BOLA before an attacker does?
Automated dynamic scanning can catch a meaningful share of BOLA if it's specifically configured to test for it — authenticating as two separate low-privilege test users and systematically attempting to access objects owned by the other, rather than just checking whether an endpoint responds. A DAST tool built with API testing in mind should support this multi-account authorization testing pattern explicitly, since generic crawling with a single test account will never surface the bug at all. Static analysis can help too, by flagging endpoints that accept an object ID parameter but don't call an ownership-check function before the database query executes, though this pattern is harder to generalize across codebases than a lot of other static checks because "what counts as an ownership check" varies by framework and team convention.
What's the actual fix?
The fix is to enforce object-level authorization as a mandatory step on every endpoint that returns or modifies a specific object — verifying the authenticated user's ID matches the resource's owner (or that the user holds an explicit grant to access it) before any data is returned, not just checking that a valid session exists. The most reliable implementation pattern centralizes this check in a shared middleware or data-access layer rather than leaving it to be reimplemented per endpoint, since a per-endpoint approach is exactly the pattern that leads to a missed check on the tenth new endpoint. Using non-sequential, non-guessable identifiers (UUIDs instead of auto-incrementing integers) doesn't fix the underlying authorization gap but does raise the cost of blind enumeration, which is a reasonable defense-in-depth layer on top of the actual fix, not a substitute for it.
How does BOLA fit into a broader API security program?
BOLA is one symptom of a broader category — that APIs, especially ones built and extended quickly, tend to under-invest in authorization logic relative to authentication logic — and a program that only checks for it as a one-time audit will keep finding new instances as new endpoints ship. Building automated authorization testing into the regular testing cycle, alongside SCA for dependency risk and static analysis for code-level bugs, is what keeps this from being a permanent, growing backlog rather than a one-time cleanup project.
FAQ
Is BOLA the same as broken access control?
BOLA is a specific type of broken access control — it refers to object-level checks. Broken access control is the broader OWASP category that also includes things like privilege escalation and missing function-level authorization.
Can rate limiting stop BOLA exploitation?
It can slow down bulk ID enumeration but doesn't fix the underlying vulnerability — a determined attacker with a single confirmed unauthorized access has already succeeded, rate limit or not.
Do API gateways prevent BOLA automatically?
No. API gateways handle authentication, routing, and rate limiting well, but object-level authorization depends on application-specific business logic that a gateway generally has no visibility into.
Why do automated scanners miss BOLA so often?
Because the vulnerable response looks structurally identical to a legitimate one — no error, no anomaly — scanners need to be explicitly configured with multiple test accounts to compare authorized versus unauthorized responses, which many default scan configurations don't do.