A practical guide to web app and API authorization testing with a role-action-object matrix and negative tests for IDOR/BOLA, functions, properties and tenant isolation.
- Authentication establishes identity; authorization decides what that identity may do to a function, object, property and tenant.
- A role × action × object/data matrix turns business rules into repeatable negative tests.
- UUIDs only make identifiers harder to guess; every request still needs a server-side policy check on the actual object and tenant.
- Evidence must cover both the response and effects in databases, queues and downstream services.
How authorization differs from authentication
Authentication answers who is making a request. Authorization answers whether that identity may invoke this function, on this object, with these properties, inside this tenant. An API may have login, valid tokens and hidden admin buttons yet remain vulnerable when the server trusts an ID or role supplied by the client.
Web app and API authorization testing should not stop after one administrator completes the happy path. Prepare anonymous, standard user, manager and administrator identities, plus at least two independent accounts or organizations for a multi-tenant system. Exercise each sensitive request with both an allowed identity and identities that must be denied.
This guide focuses on object-, function-, property- and tenant-level boundaries reflected in the OWASP API Security categories. It is a contextual self-review baseline; run active tests only on explicitly authorized assets, accounts and environments.
- Authentication: identity, session, token, issuer, audience and revocation state.
- Authorization: role, action, object, property, ownership relationship and tenant.
- Enforcement: a server-side decision on every request, not a UI or client assertion.
- Evidence: test identity, request, expected result, response and actual side effect.
A 403 response does not prove authorization is safe if data was already read, changed or sent downstream.
Inventory identities, roles, objects and tenants
Before API authorization testing, list the real actors: anonymous visitors, customers, staff, managers, administrators, service accounts, webhooks and background jobs. Record how each actor gains access, whether that access expires, and what happens when someone leaves a group or tenant.
Then inventory valuable objects and flows: profiles, orders, invoices, files, reports, API keys, invitations, exports, settings and approvals. Include list, search, batch and download endpoints, GraphQL resolvers, WebSockets and signed URLs; exposure often occurs through a secondary path rather than the main detail page.
For SaaS, a tenant boundary is more than an organization_id column. It can appear in cache keys, object-storage paths, queue messages, search indexes, report exports and third-party connections. Follow data across the complete flow instead of ending the inventory at the HTTP route.
- Identities: anonymous, user, manager, admin, support, service account and job.
- Objects: records, files, reports, secrets, configuration, invitations and exports.
- Relationships: owner, team member, share recipient, approver and tenant.
- Access channels: UI, REST, GraphQL, mobile, webhooks, queues and storage.
Build a role × action × object/data matrix
An access-control matrix turns a vague policy into testable conditions. Rows represent roles or relationships; columns represent actions such as list, read, create, update, delete, approve, export, share and administer. Each cell records allow or deny plus ownership, tenant, state and property conditions.
Roles alone are insufficient. A user may read their own profile but not another user's; a manager may approve a team order but not one they created; support may see status but not payment details. These conditions must become test cases instead of remaining only in a business document.
Create at least one positive test for every allowed cell and a negative test at every boundary: wrong user, wrong tenant, invalid state, lower role, out-of-scope field or excessive action. Store the matrix with the endpoint inventory so it can be rerun when APIs, roles or workflows change.
- Record actor, action, object, condition and property scope for each rule.
- Pair allowed behavior with a positive test and every boundary with a negative test.
- Verify deny by default for new routes and undeclared actions.
- Move stable cases into CI as authorization regression tests.
Test horizontal IDOR and BOLA
IDOR commonly describes an application accepting a client-controlled identifier and accessing an object without an authorization check. For APIs, OWASP uses the broader Broken Object Level Authorization category, or BOLA. Create an object as account A, sign in as account B with the same role, and replace IDs, parent IDs, queries, bodies or paths to attempt reading, changing and deleting A's object.
Do not test only GET /items/{id}. Verify that lists and searches apply ownership and tenant filters, exports do not mix data, downloads check access, batch operations authorize every object, and nested routes validate both parent and child. Retest objects after deletion, archiving or ownership transfer.
A UUID or random identifier makes guessing harder but is not authorization. An identifier can leak through logs, referrers, email or browser history. The server must query within the caller's permitted scope or evaluate a policy against the loaded object on every request.
- Cross-user: change an ID to reach another user's object at the same role.
- Cross-parent: keep a child ID but change the organization, project or account.
- List/search/export/file: inspect filtering, counts, metadata and download URLs.
- Batch/GraphQL: authorize every node, object and resolver.
Test function-level and property-level authorization
Broken Function Level Authorization arises when a lower-privilege user can discover and invoke a function intended for a higher role, such as administration, approval, refunds, account suspension or full exports. Call the function directly with a lower role, vary HTTP methods, try older supported API versions and bypass the UI.
Broken Object Property Level Authorization concerns fields. A response may disclose cost, role, tokens, internal notes or personal data; a request may allow mass assignment of owner, price, status, approved or isAdmin. Include fields hidden by the UI and properties nested in objects or arrays.
Use allowlisted request and response properties for each operation and policy, then inspect the stored object after the request. A 200 that silently accepts an excessive property is a failure; so is a 403 returned after the database has already changed.
- Call admin, approve, refund, export and user-management routes as a lower role.
- Vary methods, content types, API versions and equivalent paths.
- Add owner, tenant, role, price, status, approval and internal-note fields.
- Compare both response schemas and persisted data for each role.
Run end-to-end tenant isolation testing
Tenant isolation testing needs at least two tenants with distinct synthetic data. Create objects in tenant A, then use an identity from tenant B through paths, queries, bodies, headers, GraphQL variables, file keys and share links. Repeat with equal roles so organizational separation is not confused with role separation.
Check indirect data too: autocomplete, counts, analytics, email, notifications, audit logs, search indexes, caches, exports and background jobs. A response that hides content but reveals another tenant's filename, record count or activity timing may still leak metadata.
Service-to-service access and support impersonation require explicit scopes. Internal tokens should not automatically read every tenant; support access needs a reason, a time limit and an audit trail. After membership changes, tenant transfers or revocation, verify that caches and old tokens no longer grant access.
- Use two tenants and several roles with distinguishable synthetic data.
- Exercise boundaries in databases, caches, search, files, queues and downstream services.
- Test membership changes, tenant transfers, revocation and surviving sessions/tokens.
- Log acting identity, tenant, object, action, decision and correlation ID.
Negative tests, evidence and side-effect verification
A useful case records identity, tenant, role, endpoint, request, object, preconditions, expected outcome and actual result. For denials, do more than compare a 401 or 403: ensure the body exposes no restricted fields and verify that databases, queues, email, files and webhooks contain no unauthorized effect.
Stable cases should run automatically after policy, endpoint and schema changes. Automation is valuable for large role/object matrices but does not infer every business precondition. Manual review remains necessary for multi-step workflows, derived permissions, rare states and support or approval flows.
Logs should support investigation without unnecessary collection. Record acting identity, role, tenant, suitable object type/ID, action, allow/deny decision, policy version and correlation ID; never record raw tokens, secrets or sensitive payloads that are not needed.
- Keep a positive baseline and negative control for each important boundary.
- Inspect responses and effects in databases, queues, email, files and downstream services.
- Automate regression cases while retaining contextual manual review.
- Preserve minimal, redacted evidence and assign a remediation owner.
Release gates, remediation and independent assessment
Before release, prioritize every path that enables cross-tenant access, unauthorized object reads or writes, privileged functions or sensitive-property changes. After remediation, replay the original proof, a negative control and a positive test so the policy blocks the abuse without breaking legitimate use.
Scanners can discover endpoints, schemas and some response patterns, but they rarely know who owns an object, which tenant is the boundary or which action causes a downstream effect. A scanner result alone should not be presented as proof of safe authorization. Multi-tenant products, sensitive data, payments, complex administration and public APIs merit a review built around test identities and a specific threat model.
Friday Works assesses websites, web apps and APIs within an agreed scope, focusing on authentication, object/function/property authorization, tenant isolation and critical flows. Deliverables include reproducible evidence, remediation priority, guidance and in-scope retesting—not a claim that one scan is a complete penetration test or an absolute security certificate.
- Block release for cross-tenant access or unauthorized critical data/functions.
- Retest the original evidence and add a positive regression test.
- Record owner, due date, residual risk and the go/no-go decision.
- Consider an independent assessment when boundaries or business impact are complex.
FAQ
Frequently asked questions
How is authorization different from authentication?
Authentication establishes who sends a request; authorization decides which functions, objects, properties and tenants that identity may access. A valid token does not grant access to every identifier or route.
What are IDOR and BOLA vulnerabilities?
IDOR is object access through a client-controlled reference without an adequate permission check. OWASP uses BOLA for the broader API object-authorization category. Test with multiple identities across IDs, objects, parents, lists, files and batches.
Do UUIDs prevent IDOR?
No. UUIDs make identifiers harder to guess, but they can leak through logs, links, email or clients. The server still needs ownership, tenant and policy checks on every request; randomness is only defense in depth.
How should tenant isolation be tested?
Prepare at least two tenants with distinct synthetic data and equivalent roles, then attempt cross-tenant access through paths, queries, bodies, headers, files, search, caches, exports and jobs. Inspect metadata and downstream effects too.
Can a scanner find every API authorization issue?
No. Scanners help with inventory and known patterns but usually cannot infer ownership, tenant boundaries, business states, sensitive fields or asynchronous effects. Use an access matrix, real test identities and contextual manual review.
When is an independent web app and API security assessment appropriate?
Consider one before a major launch or when the system has multiple tenants, sensitive data, payments, complex administrative rights or public APIs. A useful scope includes test accounts, clear boundaries, reproducible evidence, remediation priorities and retesting.
References
Sources used in this guide
We prioritise official guidance and primary technical sources. Visit each source for full context and the latest updates.
- API1:2023 Broken Object Level AuthorizationOWASP Foundation ↗
- API3:2023 Broken Object Property Level AuthorizationOWASP Foundation ↗
- API5:2023 Broken Function Level AuthorizationOWASP Foundation ↗
- Insecure Direct Object Reference Prevention Cheat SheetOWASP Foundation ↗
- Authorization Cheat SheetOWASP Foundation ↗
- Authorization Testing Automation Cheat SheetOWASP Foundation ↗
- Authorization Testing Automation: Regression TestingOWASP Foundation ↗
- Testing for Insecure Direct Object ReferencesOWASP Web Security Testing Guide ↗
