Object-level authorisation
Changing an identifier in a request does not return somebody else's record.
- Applies to
- apps
- Standard references
- CWE-639
A finding here is not a failure
Software of any size carries something. A listing that raises findings on this check is still sold, with the findings published and their severity and reachability stated. A badge that only ever said pass would teach people to stop reading it.
Explainer · 2026-09-30
Object-level authorisation: changing an ID should never hand you someone else's record
An API that checks you are logged in but not whether the record you asked for is yours will serve every user's data to anybody willing to change a number in a request.
What this row checks
That changing an identifier in a request does not return somebody else's record. Verified the same way as row-level security: with two accounts, one owning a record and the other asking for it by its identifier.
Why it is the first API risk
Broken object-level authorisation is first on the OWASP API Security Top 10 for 2023. It is common because it is easy to write: the handler checks that the request carries a valid session, looks up the object by the identifier in the path, and returns it, without ever asking whether this user may see this object.
Sequential or guessable identifiers make it trivial to exploit, and random ones only make it slower. The fix is the ownership check itself, on every object, on every route that takes an identifier.
Where it hides
The routes people test are the ones that read a single record. The ones that leak are often the others: an update or a delete that trusts the identifier in the path, a nested route that checks the parent and not the child, a list endpoint whose filter accepts somebody else's account number. A test with two accounts has to try each kind.
Agent tooling adds a quieter version. An MCP server that fronts a multi-tenant service with one shared credential can fetch any tenant's records, so the ownership check has to happen in the server, because the service behind it will answer whatever it is asked.
How apps and templates are read for this row
On an app or a template, this row is also answered every night by a reading of the package's published files, never by running it. The rules are app check set v1.0, each with its mapping, an example, the nearest writing it leaves alone, a hand count across every app and template listing, and what a reading of files does not cover.
In the glossary: BOLA.
What this check has found
Nothing in the catalogue has raised a finding on this check. That is a fact about what has been tested so far rather than a guarantee about what is out there, and it is printed because a check that never fires is worth knowing about too.
Every listing in the catalogue shows its result on this check, with the findings summarised in public and the full report to whoever bought it. Open the catalogue.