← Concepts

阅读中文版本

Object-Level Authorization

Object-level authorization checks that the requester owns or may access each specific object by id, not merely that they hold a valid session — the flaw behind IDOR and BOLA.

security

Definition

Object-level authorization verifies permissions per object instance on every request touching that object. It differs from function-level authorization, which gates endpoints. BOLA — broken object-level authorization, the API top-ten leader — is the missing check that lets one tenant read or mutate another by changing an identifier in the URL or body.

Context and scope

Applied in API handlers, GraphQL resolvers, and ORM query scopes. Enforced through ownership filters in queries, policy layers, and multi-tenant row scoping rather than point checks after fetch.

Common misconceptions

  • Authentication implies authorization — being logged in says nothing about owning object 42
  • Using UUIDs instead of sequential ids prevents access — unguessable ids reduce enumeration, not authorized access when ids leak via lists or logs
  • A check at the endpoint is enough — the check must bind the user to the exact row in every query, including bulk and nested paths

Anti-patterns

  • Fetching by id then filtering results and leaking existence or side effects before the check
  • Enforcing ownership on GET but not on PATCH or DELETE, assuming the client follows the happy path
  • Trusting tenant ids from the request body instead of deriving them from the authenticated principal

Related concepts

Related examples

Authoritative source

https://owasp.org/www-project-top-ten/2021/A01_2021_Broken_Access_Control

What it is

Access control has two layers: may you use this function, and may you use it on this object. The second layer fails quietly: endpoints return 200 for any valid session and any id, and cross-tenant reads become one curl away.

How it works

The robust pattern scopes queries by the authenticated principal: WHERE id = :id AND owner_id = :user, or database row-level security policies bound to session variables. Framework middleware and ORMs support default scopes so handlers cannot accidentally fetch without them. GraphQL adds nested-object paths that each need enforcement.

When to apply

Every handler touching an id, including admin surfaces — internal tools leak data too. Write automated tests that request each object as two different users and assert the second gets 404 or 403, not the payload.

Pitfalls

Post-fetch checks leak object existence and timing. Bulk endpoints multiply the surface: each id in a batch needs scoping, not just the first. Mass assignment pairs with BOLA when clients can send owner_id fields and the model binds them.