Broken Object Level Authorization (BOLA), number one in the OWASP API Security Top 10 for 2023, happens when an API accepts an object ID from the client and does not check that the caller may access that specific object. The fix is an ownership check on every request that touches a record.
Authentication or authorization?
Search phrases often say "broken object level authentication," but the item is about authorization. Authentication asks who you are. Authorization asks what you may touch. In BOLA the user is logged in and is allowed to call the endpoint. The violation happens at the object level, when they change the ID to someone else's.
OWASP draws a useful line here. If an attacker reaches an endpoint or function they should not have at all, that is Broken Function Level Authorization, a different item. BOLA is the same endpoint with the wrong object.
How does it happen?
APIs commonly pass object IDs from the client, and the server uses them to decide which record to fetch. OWASP rates exploitability as easy and prevalence as widespread, because the IDs are visible in paths, query strings, headers or bodies, and the response usually reveals whether the attempt worked. IDs may be sequential integers, UUIDs or strings, and the type does not matter.
Consequences range from data disclosure to modification or deletion, and in some cases full account takeover.
OWASP's own scenarios show the range: a shop revenue endpoint where changing the shop name returns other shops' sales data, a vehicle API where the VIN is not checked against the logged-in user, and a document service where a delete request for someone else's document ID succeeds.
What does it look like in code?
A constructed example for an order API. The vulnerable handler logic, described in words: it receives an order ID, looks up the order by ID, returns it. The check that the order belongs to the caller is missing.
GET /api/orders/1001 returns the caller's order
GET /api/orders/1002 returns somebody else's order (BOLA)
The corrected logic looks up the order by ID and by the caller's account together. If no row matches, the answer is "not found," which also avoids confirming that the ID exists.
Comparing the user ID in a token with the ID in the request is not enough, OWASP warns. That solves only a small subset of cases, since many objects belong to teams, organizations or hierarchies, not to one user.
How do you prevent it?
OWASP's guidance, in short: implement an authorization mechanism that relies on user policies and hierarchy, and use it in every function that takes an input from the client to access a record. Prefer random, unpredictable values as record IDs. Write tests that evaluate the authorization mechanism and do not deploy changes that make them fail.
Random IDs are defense in depth, not a fix. OWASP's cheat sheet on insecure direct object references says the same: complex identifiers help, but access control is crucial even with them.
How to check or apply this
- List every endpoint that takes an object identifier in the path, query, header or body.
- For each, find the line where ownership or permission is checked. If you cannot find it, that is the bug.
- Centralize the check. A shared policy function or framework feature beats copying checks into every handler.
- Scope queries to the caller: look up by ID and by tenant or owner at the same time.
- Return the same error for "does not exist" and "not yours."
- Write a test per endpoint with two users. User B requests user A's object and must be refused.
- Run those tests in CI and block merges when they fail.
- Review nested routes and bulk operations, where checks are skipped most often.
- Log denied object access and alert on bursts of them from one account, which can indicate ID enumeration.
Which endpoints are most often missed?
Bulk and batch endpoints, export and report downloads, webhook and callback handlers, file download links, GraphQL mutations that take IDs in variables, and older API versions that stayed alive after a rewrite. Searches and listings also leak when a filter is applied on the client and not on the server.
Quick check
Do UUIDs prevent BOLA?
No. They make guessing harder but do not check permission. If an attacker learns an ID, from a log, a shared link or another endpoint, an unprotected API will still serve it.
What is the difference between BOLA and IDOR?
They describe the same underlying flaw, a missing object-level access check. IDOR is the older web term and BOLA is the API Security Top 10 name.
Sources
- OWASP API Security Top 10 2023: API1 Broken Object Level Authorization
- OWASP Cheat Sheet: Insecure Direct Object Reference Prevention
- OWASP Cheat Sheet: Authorization
Last reviewed: 18 October 2026.