Phase 04 🔑

Authentication & Session Testing

Identity and access controls

Methodology for testing login flows, token handling, MFA, and session management – including stealth techniques and cross-vulnerability chaining.

Introduction

Authentication is the front door of every application. If it can be bypassed or broken, every other security control is rendered meaningless. This document provides a structured methodology for testing authentication and session management, including reconnaissance specific to the authentication layer, techniques to reduce exposure during testing, and guidance for chaining vulnerabilities to demonstrate real-world impact.

Always obtain written, explicit authorization before testing authentication controls. Define test accounts for each user role before testing begins. Never test against real user accounts.

The attacker’s perspective: if I can authenticate as someone else — or maintain an authenticated session beyond its intended lifetime — I own the account.


Auth Recon

Before active testing, gather the following information with minimal noise. The goal is to map all authentication surfaces without triggering intrusion detection or account lockouts.

What to Identify

  • Login endpoints

    • Web: /login, /signin, /auth
    • API: /api/v*/auth/login, /api/auth/token
    • Mobile / legacy: discover any older endpoints (e.g., /mobile/login, /v1/auth) that may enforce weaker controls
  • Authentication mechanisms

    • Are JWTs, opaque tokens, or cookies used? Look in response headers, request payloads, or client-side JavaScript.
    • OAuth / OpenID providers: check for references to client_id, redirect_uri, and provider endpoints (Google, GitHub, Okta, etc.)
    • SAML endpoints: look for /saml, /sp, ACS URLs.
  • Public JWT resources

    • /jwks.json, /.well-known/jwks.json, /openid-configuration, .well-known/openid-configuration
    • Any API endpoint that returns a public key or certificate.
  • MFA implementation

    • Is MFA present? Look for TOTP setup, SMS/email OTP, backup codes, or push notifications.
    • Determine which paths skip MFA (password reset, device confirmation, legacy APIs).
  • Session management artifacts

    • Cookie names (e.g., session, JSESSIONID, auth_token) and their attributes (HttpOnly, Secure, SameSite, Domain, Path).
    • Any token passed via URL parameters (a critical red flag).
  • Password reset / account recovery flows

    • Find the reset endpoint, check if it uses a token that can be enumerated or has weak entropy.

How to Gather Discreetly

  • Use passive sources first: developers’ documentation, public repositories, client-side JavaScript (in developer tools without active scanning).
  • Perform a single, legitimate login with a test account and record all traffic (request/response) using a like‑browser User‑Agent (e.g., Chrome on Windows) to avoid appearing as an automated scanner.
  • Avoid using automated spiders or crawlers against login pages; manually browse only the pages necessary to locate auth endpoints.
  • Never perform password guessing or token brute‑forcing during recon.

Auth OPSEC

Every test must be conducted in a way that minimises the risk of alerting the target’s security operations or affecting real users.

General Stealth Principles

  • Test with only your own accounts – this alone eliminates most operational risk.
  • Use low‑rate, controlled probes. For example, when testing rate limiting, send 10–20 authentication attempts in a deliberate burst, then stop. The absence of a lockout or 429 response is the finding; actual stuffing is never required.
  • Mimic legitimate client behaviour.
    • Use standard browser TLS fingerprints (e.g., Chrome, Firefox) – avoid default tools like curl or Python requests that can be identified by JA3/JA4.
    • Set realistic request intervals, adding small random jitter (e.g., 200–500 ms) between requests.
    • Use a consistent User-Agent, Accept-Language, and header order matching the logged‑in browser.
  • Rotate IP addresses only if authorised and only when testing IP‑based lockouts. Using a pool of proxy IPs can alert fraud detection systems; it is often safer to report that lockout is per‑IP based on the observed behaviour without demonstrating the bypass.
  • Avoid active scanning of authentication endpoints. Scanners like Burp’s active engine may send malicious payloads (' OR 1=1 --, etc.) that trigger WAF alerts. Manual testing is the standard.
  • Always stop immediately if a test accidentally grants access to another user’s data or an administrative function. Document the conditions and report, do not escalate further.

Timing & Lockout Awareness

  • Determine whether lockouts are account‑based or IP‑based by studying the application’s response to a few failed attempts from different IPs (use authorised test environments, not production if possible).
  • Never lock a real user account. Before testing, confirm with the system owner that your test account can be unlocked, or schedule tests during a maintenance window.
  • If you observe behaviour that could lead to a denial of service for legitimate users (e.g., a global lockout), stop and report immediately.

Credential Stuffing

Purpose of the Test

Assess whether the application resists automated login attempts. Real credential stuffing is never needed; the goal is to demonstrate missing controls.

Impact

  • Account takeover for users who reuse passwords.
  • Access to sensitive data (PII, financial, health).
  • Possible lateral movement if compromised accounts have elevated privileges.

Stealth Considerations

  • Use only generated test credentials, never real breach data.
  • Limit probes to 10–20 requests at a rate mimicking human typing (e.g., 2–3 per second, then pause).
  • Check for timing differences between valid and invalid usernames to detect user enumeration without triggering lockouts – a single request with a valid test user vs. an invalid random user is often sufficient.

Testing Flow

flowchart LR
    A["LLM ideation"]
    B["Human review"]
    C["Controlled low‑rate probes"]
    D["Document findings"]
    E["Stop"]
    A --> B --> C --> D --> E

Manual Testing Steps

  1. Create a test account; record the successful login request.
  2. Send 10 failed attempts for the test account (wrong password) in quick succession.
  3. Observe responses: lockout message, CAPTCHA challenge, HTTP 429, or consistent 200 with error.
  4. Determine if lockout is account‑based or IP‑based (test with different IPs only if authorised).
  5. Check if a successful login resets the failed counter.
  6. Repeat the same low‑rate probe on the password reset endpoint – it often lacks the same rate limiting.

Expected Outcomes

Positive finding: No rate limiting, no account lockout, no CAPTCHA, no IP throttling.
Clean result: Rate limiting active (e.g., 5 attempts/minute), account lockout after N failures, CAPTCHA on repeated failures, anomaly detection.


JWT Weaknesses

Purpose of the Test

Identify implementation errors in JSON Web Token handling that allow token forgery or algorithm confusion.

Impact

  • Bypass authentication entirely (e.g., alg: none).
  • Forge tokens for any user if the secret is weak or public key misused.

Key Attack Vectors (ordered by exploitability)

  1. alg: none – Remove signature; server accepts unsigned token.
  2. Algorithm confusion (RS256 → HS256) – Use the RSA public key as HMAC secret to sign tokens.
  3. Weak secret cracking – Brute‑force HMAC secret offline (e.g., via hashcat).
  4. kid header injection – If the kid value is used in a database lookup or filesystem path, it may allow SQL injection or path traversal directly inside the JWT header.

Stealth Considerations

  • Only modify tokens belonging to your own test account.
  • When testing kid injection, use benign payloads that do not corrupt server state (e.g., /dev/null path traversal first).
  • Do not attempt to forge tokens for high‑privilege accounts; if a weakness is found, report with proof using your own low‑privilege token.

Manual Testing Steps

  1. Obtain a valid JWT from your test account login.
  2. Decode the token (base64url decode header and payload).
  3. Test alg: none: change header to {"alg":"none","typ":"JWT"}, keep payload, remove signature, submit.
  4. Test algorithm confusion: obtain public key from /jwks.json or similar, use it as an HMAC‑SHA256 secret. Sign a modified token with the alg header set to HS256.
  5. Crack HMAC secret: hashcat -a 0 -m 16500 jwt.txt wordlist.txt.
  6. Test kid injection: if a kid header exists, try ../../../../dev/null or SQL injection payloads (123' UNION SELECT 'secret'--), always using your own token.

Expected Outcomes

Positive finding: Server accepts a forged token.
Clean result: Strict server‑side validation of algorithm and key, rejection of none, public key not accepted as HMAC secret.


OAuth Misconfiguration

Purpose of the Test

Identify weaknesses in OAuth 2.0 flows: redirect_uri validation, CSRF via missing/static state, token leakage, and missing PKCE.

Impact

  • Full account takeover if redirect_uri can be manipulated.
  • Session hijacking via CSRF on the OAuth callback.

Advanced Bypass Techniques

  • Subdomain/path confusion: https://app.example.com.attacker.com or https://app.example.com/callback/../../../attacker.
  • Open redirect on allowed domain: Even if the redirect_uri is strictly allowlisted, an open redirect on that domain can be chained to leak the authorization code.
  • State parameter CSRF: If the state is absent or static (not tied to the user’s session), attackers can force a victim to link their account to the attacker’s identity.

Stealth Considerations

  • Only test redirect_uri manipulation against your own OAuth client, never against production users.
  • If you discover a redirect_uri bypass that could capture real auth codes, stop and report; do not demonstrate full capture.

Manual Testing Steps

  1. Initiate the OAuth flow with your test account and record the authorization request.
  2. Check for redirect_uri, state, response_type, and code_challenge (PKCE).
  3. Modify redirect_uri to an arbitrary domain; verify if the server accepts it.
  4. Test for path traversal or subdomain manipulation.
  5. Remove or reuse the state parameter across different sessions; check if login succeeds.
  6. Verify whether access tokens appear in URL fragments (implicit flow) – these can leak via browser history or logs.
  7. Confirm PKCE is enforced for public clients (SPA/mobile).

MFA Bypass

Purpose of the Test

Verify that multi-factor authentication cannot be skipped, replayed, or circumvented through alternative endpoints.

Advanced Techniques

  • Endpoint‑level MFA skip: The main /login forces MFA, but /api/v2/login, /mobile/auth, or older V1 endpoints may not. Test every login surface discovered during recon.
  • Race condition on OTP reuse: send the same valid OTP in two parallel requests. Some servers validate the code before marking it as used, allowing a brief window of reuse.
  • TOTP window abuse: The standard window is 30 seconds; if the server accepts codes up to 90 seconds, an attacker has more time to brute‑force or intercept.

Stealth Considerations

  • Only test against your own MFA‑enrolled account.
  • For OTP reuse race conditions, use a single OTP generated by your own authenticator; do not attempt to guess codes.
  • Never brute‑force TOTP codes in production – probing the window acceptance is sufficient to demonstrate risk.

Manual Testing Steps

  1. Enrol MFA on your test account.
  2. Test TOTP window: wait 60+ seconds, then submit an “old” code.
  3. Test OTP reuse: submit the same valid OTP twice in quick succession. Use a parallel request for race condition testing (two near‑simultaneous requests with the identical OTP).
  4. Check all login endpoints (web, API v1/v2, mobile) – do they all enforce MFA?
  5. Test password reset flow: after resetting a password, does the session bypass MFA on the next login?
  6. Examine backup/recovery code usage: single‑use? limited count?

Session Fixation

Purpose of the Test

Identify whether the application issues a new session token after login, and whether tokens can be forced onto a victim.

Stealth Considerations

  • Compare only your own pre‑ and post‑login session cookies.
  • Replay your own session token after logout to test server‑side invalidation – no need to involve another user.
  • Analyse cookie attributes passively; no intrusive scans required.

Manual Testing Steps

  1. Note the session cookie value before authentication.
  2. Log in and compare the cookie value; if identical, fixation is confirmed.
  3. Log out, then resubmit the old session token – if still accepted, server‑side invalidation is missing.
  4. Inspect cookie flags: It must be HttpOnly, Secure, SameSite=Lax/Strict. Broad domain scope (.example.com) should be avoided.
  5. Check if session token is ever exposed in URL parameters.

Auth Chaining

Authentication weaknesses rarely exist in isolation. World‑class testers document how multiple findings can be combined to demonstrate critical impact.

Example Chaining Scenarios

  • Rate limiting bypass + weak JWT secret
    Absence of rate limiting on the login endpoint enables an attacker to brute‑force the JWT secret offline after capturing a single token.

  • Open OAuth redirect_uri + missing state CSRF
    An attacker can craft a login link that binds the victim’s account to the attacker’s OAuth identity, then access the victim’s resources.

  • MFA endpoint skip + session fixation
    Logging in via a legacy API that lacks MFA enforcement, while the session token remains unchanged after main‑site login, allows an attacker to keep the session alive without ever touching the MFA‑protected flow.

  • Session fixation + JWT alg: none
    A fixed session token can later be upgraded if the attacker forges a JWT for the same session, effectively taking over any account tied to that session.

When a chain is discovered:

  • Document each vulnerability individually.
  • Show the combined attack path in a flow diagram.
  • Provide CVSS for the chain; often the whole is greater than the sum of its parts.
  • Always stop before exploiting the chain in a way that could affect real users.

AI-Assisted Testing

AI can accelerate analysis and pattern recognition, but must never generate or execute active attacks without human review.

Prompt Templates (used throughout the topics above)

  • Rate Limiting Analysis
  • JWT Configuration Review
  • OAuth Flow Analysis
  • MFA Implementation Review
  • Session Security Checklist

AI Hard Stops (Unchanged)

  • Never use real breach data, real user credentials, or tokens from other users.
  • Only test against owned test accounts.
  • Stop and report if a manipulation grants unintended access.
  • AI output must be reviewed and validated by a human tester.

Tools Reference

ToolPurposeSafe Usage Note
Burp SuiteIntercept and modify auth requestsManual mode only; no active scanner against auth endpoints
Browser DevToolsSession cookie inspectionLocal only
jwt.ioJWT decoderUse offline/local copy; never paste production tokens into online tools
hashcatJWT secret crackingOnly against test tokens and with prior authorisation

Mental Model

flowchart TD
    A["Auth-focused recon"] --> B["Identify all auth surfaces\nweb / API / legacy"]
    B --> C["For each surface:\nwhat trust does it grant if bypassed?"]
    C --> D["Test weakest control first\nrate limiting then session rotation"]
    D --> E["Escalate only within\nwritten authorization scope"]
    E --> F["Document: request · response · CVSS · remediation\nIllustrate the chain if multiple bugs found"]