What are we verifying?
Verify that every protected resource and privileged operation is authorized on the server according to the requesting user's effective permissions.
Broken access control occurs when an application allows an actor to access information or perform an operation outside the permissions assigned to that actor.
Authentication establishes who the user is. Authorization determines what that user is permitted to do. A successful login must never be treated as authorization to access every resource.
What should be tested?
Review authorization controls wherever users, roles, tenants or other security principals have different permissions.
| Component | Authorization test |
|---|---|
| Web pages | Verify protected pages cannot be accessed by unauthorized users. |
| APIs | Test authorization independently on each protected endpoint. |
| User resources | Verify users cannot access another user's resources. |
| Administration | Verify privileged functions require the appropriate role or permission. |
| Multi-tenant resources | Verify tenant boundaries are enforced. |
| Files and documents | Verify direct resource access is authorized server-side. |
How to identify the issue
Begin by documenting the application's intended authorization model. Do not assume that an identifier being visible in a URL represents a vulnerability.
Establish the authorization matrix
| Account | Role | Expected access |
|---|---|---|
| Test User A | User | Own resources |
| Test User B | User | Own resources |
| Test Admin | Administrator | Administrative resources |
Review the application's attack surface
- Object identifiers in URLs and request bodies.
- Administrative endpoints.
- API endpoints and HTTP methods.
- File and document access.
- Role and permission changes.
- Multi-tenant resources.
How to reproduce safely
Perform these tests only against systems, applications and environments for which you have explicit authorization. Use dedicated test accounts and non-sensitive test data whenever possible.
Test cross-user resource access
Determine whether one authenticated user can access a protected resource belonging to another user.
Procedure
- Authenticate as Test User A.
- Access a resource owned by User A.
- Record the resource identifier and request details.
- Authenticate as Test User B.
- Request User A's resource using the same application interface.
- Compare the response with the application's intended authorization policy.
Expected secure result
User B must not receive User A's protected information or be permitted to modify or delete User A's resource.
Fail condition
The test fails when User B can perform an operation that the authorization policy explicitly prohibits.
Test privilege escalation
Determine whether a lower-privileged account can perform functions reserved for a higher-privileged role.
Procedure
- Authenticate as a standard user.
- Identify an administrative operation that the user should not be permitted to perform.
- Attempt the operation through the normal application interface or an approved security-testing proxy.
- Record the server response.
Expected secure result
The server rejects the unauthorized operation.
Why does it happen?
The most common root cause is that an application identifies a resource but does not independently determine whether the authenticated principal is authorized to access that resource.
Hiding, encoding or replacing sequential IDs does not implement access control. Authorization must be enforced by the server.
How to fix it
Authorization should be enforced server-side before the application performs the requested operation.
Vulnerable pattern
$userId = $_GET['id'];
$stmt = $db->prepare(
"SELECT * FROM documents WHERE id = ?"
);
$stmt->bind_param("i", $userId);
$stmt->execute();
The prepared statement protects the query from SQL injection, but it does not establish that the authenticated user is permitted to access the selected document.
Ownership-aware query
$stmt = $db->prepare(
"SELECT *
FROM documents
WHERE id = ?
AND owner_id = ?"
);
$stmt->bind_param(
"ii",
$documentId,
$authenticatedUserId
);
$stmt->execute();
The application now verifies the resource and the authenticated user's ownership relationship together.
General remediation principles
- Enforce authorization on the server.
- Deny access by default.
- Centralize authorization logic where practical.
- Verify object ownership or permission for every protected operation.
- Protect APIs independently from frontend controls.
- Do not rely on hidden fields, UI restrictions, predictable IDs or client-side checks.
- Test authorization after every security-sensitive application change.
How to verify the fix
Verification should repeat the original test conditions after remediation. Do not mark a vulnerability as resolved solely because code has changed.
Authorization verification matrix
| Test | Expected | Result |
|---|---|---|
| User A → own resource | Allow | PASS |
| User B → User A resource | Deny | PASS |
| User → admin function | Deny | PASS |
| Admin → admin function | Allow | PASS |
| Anonymous → protected resource | Deny | PASS |
Assessment result
Tested authorization controls prevented the unauthorized operation.
The application permitted an operation outside the actor's authorized permissions.
The required resource or test condition could not be evaluated.
Not Tested must not be recorded as Pass. The result should accurately reflect what was actually verified.
What should be recorded?
Maintain enough evidence to demonstrate what was tested, what was observed, what was changed and how the final result was established.
Standards and references
| Framework | Reference |
|---|---|
| OWASP Top 10 | A01:2025 — Broken Access Control |
| CWE | CWE-284, CWE-285, CWE-862, CWE-863 |
| OWASP ASVS | Authorization controls |
| OWASP Testing | Authorization testing |