Web App Evaluation: Testing Authentication & Access Control Controls
Theory
Prerequisites
- STE-K001: What STE Is
- STE-K002: Test Case Design
- PEN-K006: Authentication Attacks (recommended)
Why This Lesson Matters
Authentication and access control failures are the top two OWASP categories by impact. In an STE context, the question is not "can I break auth" but "does the authentication implementation meet the stated requirements?" The difference matters because you may find an app that technically allows bypass under very specific conditions — but the control requirement says "MFA shall be enforced for all admin logins." One failed admin MFA bypass = one FAIL finding, regardless of how hard it was to find.
1. Authentication Controls to Evaluate
1.1 MFA Enforcement
Control requirement CSS-A01:
"Multi-factor authentication shall be required for all accounts
with administrative privilege."
Test cases:
TC-A01-001 (Positive): Admin user with MFA configured → should complete login
TC-A01-002 (Negative): Admin user with MFA disabled → should be blocked at login
TC-A01-003 (Bypass attempt): Submit valid credentials → intercept MFA challenge
→ attempt to skip the /mfa-verify step → should return 403
TC-A01-004 (API): POST /api/login with admin creds → response should include
MFA challenge, not a session token directly
1.2 2FA Logic Flaw: The Step Skip Attack
Many 2FA implementations have a hidden assumption: the server trusts that if you arrive at step 2 (MFA), you have completed step 1 (password). If the server does not enforce state transitions, you can skip step 1 entirely.
Normal flow:
POST /login {username, password} → redirect to /mfa-verify + temp session
Attack flow:
Directly request /mfa-verify + a valid MFA code (stolen TOTP) → authenticated?
Test procedure:
Step 1: Create Account A and Account B (both with TOTP MFA)
Step 2: Log in as Account A up to the MFA step; capture the temp session token
Step 3: Use Account B's credentials in step 1 only
Step 4: Use Account A's temp session token + Account B's TOTP code
Result: If authenticated as Account B without Account B's password → FAIL
2. Access Control Controls to Evaluate
2.1 Horizontal Privilege Escalation (IDOR)
Control requirement CSS-AC01:
"Users shall only access resources belonging to their own account."
Test cases (using two test accounts: USER-001 and USER-002):
TC-AC01-001: GET /api/profile/USER-001-ID with USER-001 token → 200 (positive)
TC-AC01-002: GET /api/profile/USER-002-ID with USER-001 token → 403 (negative)
TC-AC01-003: POST /api/orders/USER-002-ORDER-ID/cancel with USER-001 token → 403
TC-AC01-004: PUT /api/users/USER-002-ID with USER-001 token → 403
Evidence for each test case:
- Request with Authorization header showing USER-001's token
- Response showing 403 (PASS) or 200 with USER-002's data (FAIL)
- Confirmation that the accessed resource belongs to USER-002
2.2 Vertical Privilege Escalation
Control: "Users with role VIEWER shall not access admin functions."
Test cases (VIEWER account vs ADMIN account):
TC-AC02-001: GET /admin/users with VIEWER token → 403
TC-AC02-002: POST /admin/users with VIEWER token → 403
TC-AC02-003: DELETE /admin/users/1 with VIEWER token → 403
TC-AC02-004: GET /admin/dashboard with VIEWER token → 403 or redirect to /login
# Variations to test:
# Role parameter in request body: {"role": "admin", ...} → server-side ignore expected
# HTTP method override: X-HTTP-Method-Override: DELETE → should not bypass controls
# Predictable admin URLs not linked from UI: /admin-panel, /manage, /console
3. Session Management Evaluation
Control: Sessions shall expire after 30 minutes of inactivity.
Test procedure:
Step 1: Log in and capture session token
Step 2: Wait 31 minutes (do not interact with the application)
Step 3: Send a request with the old session token
Expected: 401 Unauthorized or redirect to login
FAIL evidence: any 200 response with active session after 30-minute inactivity
Control: Session tokens shall be regenerated after login.
Test procedure:
Step 1: Visit /login as unauthenticated user; capture session cookie
Step 2: Submit valid credentials
Step 3: Capture new session cookie
Expected: new session token differs from pre-login token
FAIL: same session token before and after login (session fixation risk)
4. OAuth & SSO Evaluation
Control: OAuth redirect_uri shall be validated against a registered whitelist.
Test cases:
TC-SSO-001: Use registered redirect_uri → token returned (positive)
TC-SSO-002: Modify redirect_uri to attacker.com → request rejected (negative)
TC-SSO-003: Modify redirect_uri to https://app.corp.local.attacker.com → rejected
TC-SSO-004: Modify redirect_uri to https://app.corp.local%[email protected] → rejected
If TC-SSO-002 or TC-SSO-003 succeed → FAIL — open redirect in OAuth flow
(Critical: attacker can steal authorization codes)
5. Common Mistakes
Mistake 1: Only testing with a VIEWER account. Horizontal escalation requires two accounts at the same level. Vertical escalation requires accounts at different levels. Always provision the minimum of two test accounts per role being evaluated.
Mistake 2: Testing access control only on GET requests. POST, PUT, DELETE, and PATCH operations may have different (weaker) access controls than GET. Test all relevant HTTP methods.
Mistake 3: Not documenting the test account configuration. Your finding says USER-001 accessed USER-002's data. The report reader cannot verify this unless the report includes: USER-001's role, USER-001's session token used, and proof that the accessed resource belonged to USER-002.
6. Practice Exercises
-
Write four test cases for this control: "Password reset tokens shall expire after 15 minutes and be single-use." Include positive and negative cases.
-
You test TC-AC01-002 (USER-001 accesses USER-002's profile) and receive a 200 response containing USER-002's name, email, and phone number. Write the complete STE finding including control reference, test case ID, evidence description, and FAIL justification.
-
An application uses JWT tokens for session management. The JWT contains
{"role": "viewer"}. Test whether modifying the role to"admin"in the payload is accepted by the server. Write the test procedure.
7. Lab
Assessment mode: flag
challenge_spec_id: 107 — 2FA logic flaw
The application has a two-step login. The 2FA step has a logic flaw.
Task: 1. Complete step 1 (password) with a low-privilege account 2. Identify the logic flaw in the 2FA state management 3. Bypass the 2FA check to access a higher-privileged account 4. The admin dashboard contains the flag
8. Framework Alignment
| Framework | Role | Competency | Confidence |
|---|---|---|---|
| CCSSF-STE | Security Testing & Evaluation | Authentication and access control evaluation | High |
| CCSSF-PEN | Penetration Tester | Authentication attack recognition | High |
| NICE 2.2.0 | Security Testing | K0009 — Application security testing | High |
9. Further Reading
- OWASP Testing Guide v4.2 — OTG-AUTHN-004 (Testing for Bypassing Authentication Schema)
- PortSwigger Authentication Labs — Directly maps to the test cases in this lesson
- NIST SP 800-63B — Digital Identity Guidelines — the authoritative MFA requirements reference
Learning Objectives
["Write a complete test case set for a 2FA enforcement control, including the step-skip bypass attempt with procedure, expected result, and FAIL evidence description", "Test horizontal privilege escalation between two accounts by attempting cross-account resource access and produce evidence showing both the VIEWER pass and the cross-account fail", "Evaluate an OAuth redirect_uri whitelist by testing four redirect_uri variants and identify which bypass variant succeeds against a poorly validated whitelist"]
Lesson Outline
Prerequisites → Why this matters → Authentication controls (MFA enforcement test cases, 2FA logic flaw step-skip attack) → Access control (IDOR horizontal escalation with two-account methodology, vertical escalation with method variation) → Session management evaluation → OAuth/SSO evaluation → Common mistakes → Practice exercises → Lab (flag, spec 107) → Framework alignment → Further reading
Challenge Lab
Reinforce your learning with a hands-on generated challenge based on this card's competency.