
Direct answer: A broken access control test should prove that every subject can perform only the allowed action on the allowed object, fields, tenant, and workflow state. Build a permission matrix first, then run paired allow-and-deny cases through the real server-side interface. Record the response, saved state, side effects, audit event, and regression-test ID; a hidden button or a successful login is not authorization evidence.
Use this checklist in five moves
- Obtain written authorization, define test accounts and data, and set stop conditions before sending active requests.
- Model subjects, actions, objects, fields, tenants, and contextual rules instead of testing only named roles.
- Pair every expected denial with an expected allow so the test distinguishes policy enforcement from a broken feature.
- Verify persistent state, background work, exports, notifications, logs, and caches—not only the HTTP status.
- Convert every confirmed boundary into a release regression test and retain the exact policy and build version.
This is a planning and verification guide, not a report about a tested target. No application, account, tenant, API, token, source repository, scanner, or production control was tested for this article. Run active tests only on systems you are authorized to assess, with approved data handling and rollback procedures. Prefer a controlled nonproduction environment; if a production check is unavoidable, use the least disruptive evidence path approved by the system owner.
What broken access control testing must prove
Authentication answers who or what presented a credential. Authorization answers whether that subject may perform this action on this resource under the current conditions. The distinction matters because an authenticated customer may read their own invoice but not another customer’s invoice, a support agent may view a case but not change payment details, and a service may create a report without being allowed to approve it.
OWASP A01:2025 Broken Access Control includes failures such as forced browsing, insecure direct object references, missing controls on write methods, privilege escalation, access-token manipulation, CORS mistakes, and server-side request forgery. The category is broad. This checklist focuses on application authorization: the policy decision connecting a subject, action, object, field, tenant, and context. Treat SSRF and CORS as adjacent test areas when they are in scope rather than claiming this one checklist covers them completely.
The goal is not to collect as many denied responses as possible. It is to produce reproducible evidence for two propositions:
- Allowed behavior remains available. The intended subject can complete the intended action on the intended resource.
- Denied behavior has no material effect. An unauthorized subject receives no protected data, cannot change protected state, cannot trigger a privileged background action, and cannot exploit an alternate channel.
EncryptCentral’s OWASP Top 10:2025 fix-first guide explains how this work fits a broader AppSec queue. The present checklist goes deeper on the A01 test design.
Start with written scope and a policy model
Do not begin by clicking through screens and changing identifiers at random. First identify who owns the system and data, which environments and interfaces are included, which accounts and tenants may be used, what data may be viewed or changed, how evidence will be stored, and which conditions require an immediate stop. Name the person who can authorize additional scope if a test crosses a service, tenant, or third-party boundary.
Next, turn the intended policy into a matrix. The OWASP Application Security Verification Standard 5.0.0 is the current stable ASVS release. Its authorization chapter separates documented rules from function-level, data-specific, field-level, contextual, trusted-service, and cross-tenant enforcement. Record the version with each requirement because wording and identifiers can change.
| Dimension | Questions to record | Example boundary |
|---|---|---|
| Subject | Anonymous user, ordinary user, administrator, service, integration, delegated actor, suspended account? | A help-desk role can reset a user factor but cannot grant itself an administrator role. |
| Action | Read, create, update, delete, approve, export, share, assign, impersonate, restore? | A reviewer can comment on a request but cannot approve their own request. |
| Object | Own record, peer record, another tenant’s record, draft, file, job, report, secret, administrative setting? | A user can download their own statement but not one associated with another account. |
| Field | Which properties may be read or written? Which values are server-derived or restricted? | A user may change a display name but not submit a role, owner, price, tenant, or approval field. |
| Context | Workflow state, time, device, location, channel, delegation, authentication strength, or recent reauthentication? | A payment-destination change requires a recent step-up check even for an otherwise authorized user. |

The matrix should include explicit deny rows. If the policy lists only what each role can do, testers may miss anonymous access, cross-tenant access, stale sessions, delegated operations, or behavior that should be denied when no rule matches. OWASP’s Authorization Cheat Sheet recommends deny by default and permission validation on every request.
Broken access control testing checklist
1. Establish the baseline
- Create or obtain approved accounts for every relevant role and at least two ordinary users. For multi-tenant systems, use controlled accounts in at least two test tenants.
- Create minimal synthetic objects with known ownership, state, and sensitivity. Avoid real customer or employee data when synthetic records can prove the boundary.
- Capture one successful request for each allowed action through the supported client. Record the route, method, object, fields, session state, build, and expected saved result.
- Confirm that logging and test-data cleanup work before negative testing begins.
A baseline prevents false conclusions. A denial may come from a broken feature, expired session, missing prerequisite, or test-data error rather than a functioning authorization check.
2. Test unauthenticated and post-session access
- Repeat protected read and write requests without a session or access token.
- Log out, then repeat requests that previously worked. Verify server-side invalidation where the design requires it.
- Check direct routes, APIs, file URLs, exports, and background-job result locations—not only navigation links.
- Verify that denial does not disclose the protected object’s existence, sensitive metadata, cached content, or a usable temporary URL beyond the application’s stated policy.
The stable OWASP WSTG 4.2 authorization guidance explicitly checks unauthenticated access, post-logout access, and access to functions reserved for another role. OWASP is developing WSTG 5.0, but 4.2 remains the stable version as of this article’s review date.
3. Test horizontal and object-level boundaries
- Using user A, repeat an allowed request against user B’s controlled object. Test read, update, delete, share, attachment, comment, and export operations that apply.
- Change every object reference the server accepts: path, query, request body, nested object, file name, batch item, GraphQL variable, or job identifier.
- Test list and search results as well as direct-object routes. A detail page may deny access while an export or autocomplete leaks the same data.
- For multi-tenant applications, test tenant-scoped records, administrative routes, bulk actions, reports, files, and asynchronous job results across tenant boundaries.
OWASP API1:2023 Broken Object Level Authorization explains that an endpoint may be legitimate for the caller while a particular object is not. Random or opaque identifiers make guessing harder; they do not replace an object-level permission check.
4. Test vertical and function-level boundaries
- Capture privileged operations with an approved administrator account, then repeat them as lower-privilege and anonymous subjects.
- Test direct requests even when the lower-privilege interface hides the control. The server must enforce the decision.
- Cover read and write methods. Check alternate methods, bulk routes, imports, exports, preview endpoints, mobile endpoints, legacy versions, and internal APIs exposed through a gateway.
- Test chained operations. A user may be unable to call “approve” directly but may be able to change state, owner, or workflow inputs that produce the same outcome.
This is distinct from object-level authorization. If the subject should never use the endpoint or operation, the boundary is function-level. If the operation is allowed but not for that object, the boundary is object-level. A finding can involve both.
5. Test field-level and mass-assignment boundaries
- Compare fields returned to different roles. Remove interface assumptions and inspect the actual response body, export, file metadata, and error details.
- Submit restricted, hidden, read-only, or server-derived fields in create and update requests. Examples include role, owner, tenant, status, price, approval, entitlement, and internal notes.
- Test partial updates, nested objects, arrays, imports, and bulk endpoints. The accepted field set may differ from the standard form.
- Verify saved state independently. A response may omit a restricted field while a background worker or data layer still accepts it.
6. Test context, state, and workflow rules
- Exercise actions before, during, and after their allowed workflow state. Try replaying an earlier approved request after the object’s state changes.
- Test self-approval, separation-of-duties rules, delegated access, impersonation, account suspension, role removal, ownership transfer, and permission changes during an active session.
- Where policy depends on recent authentication, device posture, location, time, or risk, verify both the trigger and what happens when the condition changes mid-session.
- Check race and duplicate-submission behavior safely. Confirm that concurrent or repeated requests cannot bypass a one-time decision or create a partially authorized result.
Business rules often carry the most consequential authorization decisions. A generic scanner may recognize a missing route check but cannot infer that the requester must not approve their own refund or that a record becomes immutable after a legal hold.
7. Test tokens and service-to-service decisions
- Verify that the resource server uses the intended issuer, audience, subject, scope, and authorization claims; a valid signature proves integrity, not permission for every resource.
- Test missing, reduced, excessive, stale, and revoked scopes or roles with approved test identities.
- Trace delegated calls across services. Confirm that downstream authorization preserves the originating subject and tenant where policy requires it.
- Verify permission changes take effect within the documented interval. If self-contained tokens delay enforcement, document the risk, token lifetime, revocation or detection control, and tested behavior.
8. Verify denial, evidence, and detection
A status code is only one observation. For each deny case, verify the response contains no protected data, persistent state is unchanged, no file or temporary URL was created, no message or webhook was sent, no background job ran, no cache now exposes the object, and no unauthorized relationship was added. Confirm that useful access-control failures reach the audit trail without logging secrets or unnecessary sensitive data.
Then run the paired allow case again. A control that blocks everyone is an outage, not a correct authorization implementation.

Use an evidence-producing test record
One concise record per boundary makes triage and regression possible. Use stable test-case identifiers and keep secrets, full tokens, and unnecessary personal data out of evidence.
| Field | What to capture |
|---|---|
| Identity | Case ID, application, environment, build, policy version, ASVS version, owner, and date |
| Policy | Subject, action, object, field, tenant, context, and expected allow or deny decision |
| Preconditions | Approved account, synthetic object, workflow state, required feature flag, and cleanup plan |
| Execution | Sanitized request description and the single controlled change from the allowed baseline |
| Observations | Status and response shape, saved-state read-back, side effects, audit event, alert, and cleanup result |
| Outcome | Pass, fail, blocked, or not applicable with evidence links and limitations |
| Follow-through | Root cause, fix owner, retest result, regression-test ID, exception owner, and expiry |
The OWASP Authorization Testing Automation Cheat Sheet models authorization using feature, role, and data dimensions and recommends running the tests with each release. Expand that model when the application also depends on fields, tenants, workflow state, or contextual attributes. Automated cases are excellent for known boundaries; retain manual, threat-led testing for new workflows and complex business logic.
Fix and regression-test the root cause
Repair the enforcement point, not the visible symptom. Prefer a reusable, trusted service-layer authorization mechanism that denies by default and receives the subject, action, object, tenant, and relevant context. Do not rely on client-side conditions, route obscurity, identifier randomness, a gateway that lacks object context, or a token claim the application never validates.
After the fix, rerun the original case, adjacent objects and operations, every affected role, at least one legitimate allow case, and failure or rollback paths. Read back the deployed configuration and saved data. If the issue crossed multiple services, verify each enforcement point and the propagated identity. Connect the regression to the build pipeline so a later route, role, or serializer change cannot silently reopen the boundary. EncryptCentral’s API endpoint security guide offers broader API context, while the secure coding overview provides foundational development practices.
Common failure modes
Testing only what the interface displays
Hidden buttons and missing menu items improve the experience but do not prove server-side enforcement. Test the underlying request and alternate supported channels.
Changing an ID and stopping at the response
An error body may hide a write that already happened. Always read back the object, related records, files, jobs, notifications, logs, and caches that could carry a side effect.
Using one administrator and one user
That pair misses peer access, tenant boundaries, delegated actors, services, suspended accounts, field restrictions, workflow states, and contextual decisions. Build the model from policy, not from the easiest accounts to obtain.
Treating a scanner label as proof
Tools can replay matrices and identify inconsistent responses, but they do not know every business rule. Reproduce the behavior, confirm the policy, verify impact safely, and preserve the evidence.
Declaring success after one denial
A single denied route can coexist with an allowed export, batch endpoint, mobile API, background job, or stale token. Coverage is the set of material paths, not one screenshot.
Decision
A useful broken access control test plan begins with policy and ends with retained proof. For one application, list the subjects, actions, objects, fields, tenants, and contexts that matter. Pair allowed and denied cases, exercise the real server-side paths within written scope, and verify every material side effect. Turn confirmed boundaries into versioned regression tests and rerun them whenever roles, routes, serializers, services, workflow rules, or trust boundaries change.
The first deliverable should be a small, owned matrix covering the application’s highest-consequence actions and data—not a claim of complete OWASP coverage. Expand it as the system changes, and treat any unmodeled decision as a reason to clarify policy before assuming access is allowed.






