Broken access control

The server lets a user read data or perform an action their account, role, or tenant was never supposed to reach.

users can see each other's datanormal user can open the admin pagechanging the URL shows another accountforgot the permission checkI can do things my role should not allowbroken autorizationthe button is hidden but the API still worksany logged-in user can grab another user's stuffwe only check permissions in the frontend

See it

Live demo coming soon

What it is

Broken access control means the server accepts an action the current user is not allowed to perform. Reading another tenant's invoice by changing an id, calling an admin endpoint as a regular user, editing a read-only record, and downloading a file through a guessed URL are all the same family. IDOR is its familiar object-level form, and OWASP put this category at A01 in the 2021 Top 10, ahead of injection.

Reach for it whenever an endpoint loads or changes something owned by a user, role, organization, or subscription tier. Put the authorization decision on the server, close to the data access, and make the resource and action explicit. Hiding a button can improve the interface, but it does not enforce a rule against someone sending the HTTP request directly.

The usual mistake is fixing only the route that appeared in the report. The same resource often has read, update, delete, export, search, file, GraphQL, and background-job paths. A durable fix centralizes the policy, defaults to deny, scopes database queries by tenant or owner, and tests the full matrix of roles, actions, and resource ownership.

Ask AI for it

Fix broken access control across this application. Build an explicit authorization matrix of roles, actions, resource types, ownership, and tenant boundaries, then trace every HTTP, GraphQL, file, export, admin, and background-job path that touches those resources. Move each decision into one deny-by-default policy layer and make owner_id or tenant_id part of the database query, using PostgreSQL row-level security where the project runs on PostgreSQL. Do not rely on hidden UI, UUIDs, or client claims. Add Playwright APIRequestContext tests that try every forbidden role and cross-tenant combination for read, create, update, delete, and export, asserting no sensitive data appears in the response.

You might have meant

idorleast privilegetenant isolationrow level securityprivilege escalation

Go deeper