If you had to pick the two areas of security testing most likely to yield real, high-severity bugs, they would be authentication and authorisation. Get either wrong and the rest of your security investment becomes irrelevant — an attacker who can bypass login or escalate their role does not need to exploit SQL injection. These two areas are also among the most commonly undertested, because developers and QA engineers focus on happy-path functionality and assume the access controls "just work."
Authentication vs authorisation: the distinction
Authentication answers: who are you? It is the process of verifying identity — login forms, passwords, multi-factor authentication, SSO tokens, OAuth flows.
Authorisation answers: what are you allowed to do? It is the enforcement of permissions — whether an authenticated user can access a specific resource, endpoint, or action.
The two are related but distinct, and both need explicit testing. A system can have strong authentication (users cannot log in as each other) while having broken authorisation (logged-in users can access each other's data). OWASP A01 (Broken Access Control) and A07 (Identification and Authentication Failures) are different categories because the failures are different.
Authentication testing checklist
A systematic authentication test covers these scenarios:
Basic login:
- Valid credentials → success
- Invalid password → failure with a generic message (not "password incorrect" — that confirms the username exists)
- Non-existent username → same generic message as invalid password (prevents username enumeration)
Brute-force protection:
- After 5–10 failed attempts, is the account locked or rate-limited?
- Are there CAPTCHA challenges after repeated failures?
- Are failed attempts logged?
Password quality:
- Does the application accept weak passwords like "password123" or "111111"?
- Is the minimum length enforced?
- Are common passwords (from known breach lists) blocked?
Session management:
- After logout, is the session token invalidated server-side? (Try replaying the old token after logout — it should return 401.)
- Does the session expire after a reasonable period of inactivity?
- Does the "remember me" cookie have an appropriate expiry (not indefinite)?
Password reset:
- Is the reset token single-use? (Use it once, try again — should fail.)
- Does the token expire? (Try a token from an email 24 hours old.)
- Does the reset link work even after the user logs in and changes the password through another path?
Multi-factor authentication:
- If MFA is required, can it be bypassed by navigating directly to a protected URL after the first factor?
- Are backup codes rate-limited?
Authorisation testing: the matrix approach
Authorisation testing is systematic by nature. The inputs are your roles and your resources; the expected output for every combination is either "permitted" or "denied." The most reliable approach is a matrix.
Role × endpoint authorisation matrix — expected HTTP status codes
| /admin panel | /user accounts | /reports | /public pages | |
|---|---|---|---|---|
| Admin | 200 — allowed | 200 — allowed | 200 — allowed | 200 — allowed |
| Manager | 403 — denied | 200 — allowed | 200 — allowed | 200 — allowed |
| Standard user | 403 — denied | 403 — denied | 403 — denied | 200 — allowed |
| Unauthenticated | 401 — unauth | 401 — unauth | 401 — unauth | 200 — allowed |
Build this matrix for your application, then test every cell. The most common failures are the cells marked "403 — denied" that actually return 200 because the authorisation check is missing or misconfigured.
Key test patterns:
Horizontal privilege escalation (IDOR): log in as User A, access a resource owned by User B by changing the ID in the URL or API request.
Vertical privilege escalation: log in as a standard user, attempt to access an admin endpoint (/admin, /api/admin/users). This should return 403, not 404 or 200.
UI bypass: if the admin panel link is hidden from the standard user's navigation, try navigating to the URL directly. UI hiding is not access control — the backend must enforce permissions independently.
Role modification: if your application uses JWTs, decode the token and examine the payload. Can you change the role claim from "user" to "admin" and re-sign? (Proper JWT implementations verify the signature; broken ones accept whatever payload you send.) Sending a JWT with "alg": "none" is a classic test — vulnerable systems accept unverified tokens.
Token and session testing
Modern applications use tokens (JWTs, OAuth access tokens, API keys) in addition to traditional session cookies. Token-specific tests:
- Expired tokens: does the server reject tokens past their
expclaim? - Token scope: can a token issued for resource A be used to access resource B?
- Refresh token rotation: when a refresh token is used, is it invalidated and replaced? If the old refresh token still works after use, it is a security risk.
- Algorithm confusion: test
alg: noneon JWTs. Test RS256 → HS256 downgrade attacks (the server's public key used as the HMAC secret — a real vulnerability in some libraries).
⚠️ Common mistakes
- Trusting the UI as the access control layer. Hiding the admin button from standard users does nothing if the
/api/adminendpoint responds to any authenticated request. Authorisation must be enforced server-side on every request, independent of what the UI shows. - Only testing the happy path for each role. Testing that an admin can access the admin panel is a functional test. Testing that a standard user cannot is an authorisation test. Both are required.
- Forgetting API endpoints when testing a single-page app. The visible interface has links and pages. The actual access control lives on the API calls those pages make. Test the API directly — with the right tools (Postman, Insomnia, ZAP proxy) — not just the UI.
- Assuming MFA bypasses are impossible. MFA bypass attacks (session fixation, token prediction, OTP reuse) are a real category. If MFA is a security requirement, test that it cannot be bypassed by navigating directly to post-authentication URLs.
🎯 Practice task
For any application you have legitimate access to test — or a deliberately vulnerable app like OWASP Juice Shop:
- Build a role × endpoint matrix covering your application's roles and 4–6 representative endpoints (admin areas, user data, reports, public content).
- Test the three most security-critical cells — the ones where a denial that returns 200 instead of 403 would be the most damaging.
- Try at least one IDOR test: log in as one user, find a resource ID in the URL or API response, and try to access a different ID that belongs to another account.
Document the result as a formal security test finding: endpoint tested, role used, expected result, actual result, and severity. This is the output format for a real security test report.