Prompt
How do I test permissions and access control on endpoints?
Latest observation
Testing permissions and access control on endpoints is about verifying that the right users can do the right things, and everyone else cannot. A good approach combines role-based testing, authorization boundary testing, and negative testing.
1) Identify what must be protected
For each endpoint, list:
- Who can access it: anonymous, authenticated user, admin, service account, etc.
- What they can do: read, create, update, delete, export, approve, etc.
- Which resource scope applies: own data, team data, tenant data, all data.
Example:
GET /orders/{id}: owner, support agent, adminDELETE /orders/{id}: admin onlyPATCH /users/{id}: user can edit own profile, admin can edit any user
2) Create a role/permission matrix
Make a table of expected behavior for each endpoint and role:
| Endpoint | Anonymous | User | Manager | Admin |
|---|---|---|---|---|
| GET /profile | 401 | 200 | 200 | 200 |
| GET /users/{id} | 401 | 403 (other user) | 200 (team) | 200 |
| DELETE /users/{id} | 401 | 403 | 403 | 204 |
This becomes your test plan.
3) Test the main access cases
For every protected endpoint, test these cases:
Authentication
- No token / no session → usually 401 Unauthorized
- Invalid token → 401
- Expired token → 401
Authorization
- Valid user but insufficient permissions → 403 Forbidden
- Valid user with correct role/ownership → 200/201/204
Resource ownership / tenancy
- User accessing their own resource → allowed
- User accessing someone else’s resource → denied
- Tenant A accessing tenant B’s resource → denied
Method restrictions
- Same endpoint with different HTTP methods:
GETallowed,POSTdeniedPUT/PATCHrestrictedDELETEadmin-only
4) Test negative cases aggressively
Try to break access control by modifying:
- Headers:
Authorization, custom role headers, tenant headers - Path params: change IDs to another user’s ID
- Query params:
?userId=...,?role=admin - Request body: fields like
isAdmin,ownerId,tenantId,status - HTTP method: use
PUTinstead ofPOST,DELETEinstead ofPATCH - Content type: sometimes hidden bypasses happen with alternate encodings
You want to ensure the server does not trust client-supplied authority.
5) Verify object-level authorization
A common bug is “authenticated means allowed.” Test object-level checks:
- User can only read/update/delete objects they own or are permitted to manage
- Ensure list endpoints don’t leak other users’ records
- Ensure search/filter endpoints can’t be used to enumerate restricted data
Example:
GET /documents/123should return 403 if document 123 belongs to another tenantGET /documents?ownerId=otherUsershould not reveal unauthorized documents
6) Test role escalation attempts
Check whether a user can elevate privileges by:
- Editing their own role fields
- Supplying
role=admin - Using hidden or undocumented endpoints
- Calling admin endpoints with a normal account
- Replaying another user’s token/session
- Tampering with JWT claims if applicable
Ensure the server derives permissions from trusted sources, not client input.
7) Automate tests at multiple layers
Unit tests
Test authorization logic directly:
canEdit(user, resource)returns expected result- Policy/rule engine tests
Integration/API tests
Hit the real endpoint with test users/roles:
- Assert status codes
- Assert response body doesn’t leak sensitive fields
- Assert side effects don’t happen on denied requests
End-to-end tests
Simulate user flows:
- Logged-out user
- Standard user
- Admin
- Cross-account access attempts
Security testing
Use tools like:
- Postman / Newman
- REST Assured
- pytest + requests
- OWASP ZAP for scanning
- Burp Suite for manual tampering
8) Validate both response and behavior
Don’t just check the status code. Also confirm:
- No data changes occurred on denied requests
- No partial updates
- No sensitive info in error messages
- No timing or response-size leaks that reveal existence of protected resources
9) Watch for common mistakes
Common access-control bugs:
- Missing authorization on one endpoint
- IDOR/BOLA: changing an ID exposes someone else’s data
- UI-only restrictions with no server-side enforcement
- Role checks done only on
GET, not onPOST/PUT/DELETE - Default-deny not enforced
- Mixed tenant/user scoping
- Authorization checked after the action has already happened
10) Use a simple test template
For each endpoint, define:
- Request
- Actor
- Expected status
- Expected body
- Expected side effects
- Expected logs/audit event
Example:
- Request:
DELETE /orders/42 - Actor: authenticated standard user
- Expected status:
403 - Expected body: error without sensitive detail
- Expected side effects: order remains unchanged
- Expected logs: denied access recorded
If you want, I can also give you:
- a practical API access-control test checklist,
- example test cases in Postman/pytest, or
- a matrix for roles/permissions you can reuse.