EASY
⏱ 90 min
Module 3 of 8
What you’ll learn
- Username enumeration — finding valid accounts before you crack anything
- Password spraying vs brute-force — when each technique wins
- Credential stuffing and how it differs from brute-force
- Session cookie attack patterns and the tests that catch them
- JWT weaknesses that still work in 2026 — algorithm confusion, weak signing keys, missing exp
- OAuth / SAML common flaws you should probe in every engagement
Prerequisites: Modules 1–2.
Authentication bugs are high-severity by nature. Every subsequent authorization control in the application depends on correctly identifying the user. Break authentication and you bypass everything downstream. This is why auth-layer findings consistently rank as Critical in professional reports.
Modern frameworks handle the basics reasonably well. The authentication bugs that still land in 2026 engagements are almost always configuration errors, legacy code paths, or subtle implementation flaws around edge cases. This module teaches you the test techniques that surface those.
Username enumeration
Before trying to crack passwords, determine which usernames exist. Enumeration reduces the attack surface from “every possible username” to “known-valid accounts” — often 1000x faster.
Enumeration primitives:
- Error message delta. Submit a valid username with a wrong password. Then submit a clearly-invalid username with any password. Compare responses. “Incorrect password” vs “User not found” is gold.
- Timing delta. If the app hashes a password before checking the user, valid-username requests take longer (because hashing happens) than invalid-username requests (rejected early). Automate with a few hundred requests; compute response time averages.
- Password reset enumeration. “If this email exists, we’ve sent a reset link” is meant to prevent enumeration. But some apps leak timing or response size. Test the reset flow with a known-valid and known-invalid email; compare.
- Registration. Try to register with a known-valid email. “Email already in use” = enumeration.
Automation
ffuf -w usernames.txt -X POST
-d '{"username":"FUZZ","password":"wrongpassword123"}'
-H "Content-Type: application/json"
-u https://target.example.com/api/login
-fr "User not found" # filter (exclude) responses matching this string
# Whatever response is NOT filtered = valid username detected
Password spraying vs brute-force
These two attacks target different defenses:
- Brute-force: many passwords against ONE account. Hits account-lockout policies fast. Rarely works against modern apps unless lockout is missing or bypassable.
- Password spraying: ONE password (or small set) against MANY accounts. Spreads the request load across accounts, avoiding per-account lockout. Surprisingly effective in the real world.
Password spraying execution
Build a list of enumerated usernames. Pick 3–5 likely passwords based on season, company name, culture. Typical picks for Indian enterprises in 2026: Winter2026!, {Company}@123, Password@2026, Welcome@123. Yes, they still work.
# Spray one password across all usernames
for user in $(cat usernames.txt); do
curl -s -X POST https://target.example.com/api/login
-H "Content-Type: application/json"
-d "{"username":"$user","password":"Welcome@123"}"
-w "%{http_code} $usern" -o /dev/null
sleep 1 # rate-limit yourself
done | grep "^200"
Rate-limit bypass techniques
If the target rate-limits by IP, try:
X-Forwarded-Forheader rotation — some apps trust it for rate limiting- Cycling source IPs through a proxy rotator
- Distributed spraying over many hours
- If the app tracks attempts per session, use fresh sessions per attempt
Credential stuffing
Attackers don’t guess passwords — they replay passwords that leaked from other breaches. The combolists are enormous; every major application has users who reuse credentials from breached services.
From a testing perspective, you verify the app has controls against credential stuffing, not that you can stuff specific credentials (that’s unethical). Verify:
- Have I Been Pwned integration — does the app warn/block on known-compromised passwords during registration or login?
- Anomaly detection — does the app flag unusual login locations, devices, or velocities?
- MFA coverage — is MFA mandatory, optional, or available only for admins?
- Account-takeover alerts — does the app notify users when sign-in happens from a new device/location?
Session cookie attacks
Covered in Module 1 but worth testing explicitly:
- Does the session cookie have
HttpOnly,Secure,SameSite=Laxor stricter? - Can you access the cookie via
document.cookiein the browser console? If yes,HttpOnlyis missing. - Does logging out invalidate the session server-side? Copy the cookie to another browser; log out in the first; see if the second still works. If yes, logout is cookie-delete only (broken).
- Session fixation: set your session cookie, log in, observe whether the cookie value changes. If it doesn’t, the app is vulnerable to session fixation.
- Concurrent sessions: does the app allow unlimited concurrent logins or cap them?
JWT — the 2026 attack surface
JSON Web Tokens are self-contained signed tokens carrying claims. They’re used widely for API authentication. The classic JWT attacks still land in 2026 because frameworks get them wrong:
1. Algorithm confusion (alg: none)
If the server trusts the alg field in the token header, you can set it to none and drop the signature. The server may accept the unsigned token.
# Original token
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.{payload}.{signature}
# Modified: alg=none, signature stripped
eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.{payload}.
Mitigation: server must validate alg against an allowlist.
2. Algorithm confusion (HS256 → RS256)
If the server expects RS256 (asymmetric — verify with public key), an attacker can change alg to HS256 (symmetric — sign with the public key as the secret). The server tries to verify with the public key using HMAC, and the attacker-crafted signature validates.
3. Weak signing key (HS256)
HS256 tokens signed with a short or guessable secret can be cracked offline with hashcat:
hashcat -m 16500 jwt_token.txt rockyou.txt
# Cracks HS256 tokens against a wordlist — extracts the secret
If you crack the secret, you can mint arbitrary tokens with any claims you want.
4. Missing expiration claim
Tokens without an exp claim are valid forever. Combined with any other vulnerability, this turns transient access into permanent.
5. Key confusion via kid header
Some JWT libraries look up the signing key via a kid (key ID) field in the header. If the kid is used in a database query, SQL injection is possible. If it’s used as a file path, path traversal can point to attacker-controlled content.
Tools
Use the JWT Decoder tool on RingSafe to inspect tokens. For fuzzing: jwt_tool (GitHub) automates all the common JWT attacks.
OAuth common flaws
- Missing state parameter — enables CSRF against the OAuth flow
- Redirect URI validation — if the server accepts partial-match redirect URIs, attacker redirects the code to their domain
- PKCE not enforced — public clients (mobile apps, SPAs) must use PKCE; if the server doesn’t enforce it, authorization codes can be intercepted
- Scope upgrade — initial request with minimal scopes, token refresh request with broader scopes. Some servers grant the upgrade.
- Open redirect → authorization code theft — if the callback URI has an open redirect, attacker chains it to steal codes
SAML common flaws
- Signature bypass — SAML responses are XML with a digital signature. Some parsers validate signatures but extract user identity from a different node (XPath injection territory).
- XML External Entity (XXE) — SAML parsers that allow external entities are XXE-vulnerable.
- Audience validation missing — if the
AudienceRestrictionis not checked, tokens for one application can be replayed against another. - Replay protection — SAML responses have timestamps; if they’re not enforced, replays work.
MFA bypass patterns
- MFA check is client-side only (rare but found occasionally)
- MFA enrollment endpoint callable by any authenticated user to enroll their own device for the victim’s account
- Legacy auth paths (mobile app, API) that don’t require MFA even when web does
- Backup/recovery codes without rate limiting — brute-forceable
- “Remember this device” cookies that can be harvested and replayed
Exercises
1. Username enumeration in a test app. Spin up DVWA or OWASP Juice Shop. Attempt username enumeration via the password reset flow. Quantify the response-time or response-content delta between valid and invalid emails.
2. JWT inspection. Use the JWT Decoder tool on a token from any app you use. Identify the algorithm, claims, and expiration. Does the token have a reasonable expiration? Does it include unnecessary claims (PII, role hints)?
3. Session behavior test. On a web app you have an account with: log in, copy the session cookie, paste it into a private browser window, log out of the original window, then reload the private window. Does the cloned session still work? This reveals server-side logout behavior.
Check your understanding
- Why is password spraying more effective than brute-force against modern apps?
- What’s the difference between credential stuffing and brute-force?
- Why does
alg: nonework against some JWT implementations? - What happens if a JWT has no
expclaim? - What is the “state” parameter in OAuth, and what does it prevent?
Key takeaways
- Enumerate valid usernames before cracking. Reduces attack surface dramatically.
- Spray common passwords across many accounts; brute-force is rarely worthwhile.
- JWT vulnerabilities are implementation issues — always inspect alg, signature, and exp.
- Session management is where logout and concurrent-session bugs hide.
- OAuth and SAML are complex standards; auditors routinely find redirect-URI and signature issues.
Take the 20-question quiz below to confirm your understanding. Pass with 70%+ to mark this module complete. Unlimited retries.
Module Quiz · 20 questions
Pass with 70%+ to mark this module complete. Unlimited retries. Each question shows an explanation.