Preventing Broken Object Authorization in APIs
An API can authenticate a caller correctly and still disclose another customer's invoice if object ownership is not checked. Authorization must depend on the requested resource, not on whether the caller has a session.
اقرأ بالعربية
On this page
What this addresses
An API can authenticate a caller correctly and still disclose another customer's invoice if object ownership is not checked. Authorization must depend on the requested resource, not on whether the caller has a session.
Practical implementation steps
- Define authorization policy for each resource type
- Resolve the actor's tenant and allowed scope on the server
- Filter database access using trusted authorization context
- Test cross-user and cross-tenant identifiers
- Log denials without leaking sensitive resource data
Acceptance test
Authenticate as user A and request user B's invoice identifier. The expected result is denial or non-disclosure, even if the ID format is valid.
Common failure mode
Client-side filtering, hidden buttons and unpredictable IDs are not authorization controls.
The object is the authorization boundary
An authenticated user is not automatically entitled to every invoice, project or customer record in an API. A request such as a read or update by record identifier needs an authorization decision for that record and action. Hiding the identifier, using a UUID or removing a button from the interface does not establish that decision. Define which organization owns the resource, which relationship grants access and whether the requested action differs from ordinary viewing. Apply the rule in the server path that actually reads or changes data.
Scope retrieval to the caller's permitted data
A useful design resolves the caller’s trusted identity and tenant context before obtaining the object. Where appropriate, include ownership or tenant scope in the parameterized database query. Check action permissions as well: a user allowed to view an invoice may still be forbidden to approve, export or delete it. Do not trust a tenant identifier, role or owner supplied in the request body as an authority. Nested resources require their own relationship checks; belonging to one project does not grant access to an unrelated attachment whose identifier appears in the URL.
Include bulk and indirect operations
Object authorization failures often hide in exports, search results, background jobs and batch updates rather than a single detail endpoint. A bulk request containing nine permitted identifiers and one prohibited identifier needs a documented all-or-nothing or explicitly partial response policy. A background job should retain enough trusted context to enforce the requesting user’s or service’s authorized scope. Shared caches need keys and content boundaries that prevent one customer receiving another customer’s record. Authorization should precede serialization; removing a field in the browser cannot undo an overbroad response.
Build a negative test matrix
Create two independent organizations and users with different permissions in a disposable test environment. Attempt to read, modify, delete, download and export the other organization’s resources through every supported method. Test direct identifiers, nested paths, search filters and bulk arrays. Verify both the HTTP response and database state; an error response after an unauthorized mutation is still a failure. Include disabled users, changed roles and stale sessions according to the application’s established session model. Keep test data synthetic and never probe real third-party records to demonstrate the weakness.
Choose error behavior deliberately
Use a consistent policy for forbidden and unavailable resources that suits the application’s disclosure requirements. Avoid error details that enumerate another customer’s objects. Log denied operations with useful context while excluding secrets and sensitive payloads. Central authorization helpers can reduce inconsistent logic, but they require tests showing how each resource type uses them. The success condition is server-enforced access for every object and operation, including indirect paths. A secure login screen and an opaque record identifier are useful properties, yet neither is a substitute for these object-specific controls.
Primary references and further reading
Connect the idea to your business.
Start with your goals, existing systems and constraints before choosing a solution.
IT Services
