Prerequisites
- Target system, dependencies and environment configured.
Usage
Purpose
Authentication is the front door. Weaknesses here — no lockout, username enumeration, a broken reset flow — hand attackers accounts without any clever exploit. This skill covers testing the login and account-recovery surface and closing the common gaps.
When to use it
Any app with user accounts. Test it early: auth flaws are high-impact and often shallow, so they're a fast source of real findings.
Test only accounts and apps you're authorised to. Credential attacks against systems you don't own are unauthorised access.
Procedure
- Username enumeration — does the app reveal whether an account exists? Compare responses for a valid vs invalid username on login, registration, and password reset. Different error text, different status, or different timing all leak it:
"No such user" vs "Wrong password" -> enumeration
- Brute force / lockout — try several bad passwords for one account. Is there a lockout, rate limit, or CAPTCHA after a few failures? If not, the account is brute-forceable:
ffuf -w passwords.txt -X POST -d 'user=admin&pass=FUZZ' -u https://app.tld/login -fr 'Invalid'
- Credential stuffing exposure — no rate limiting plus no MFA means leaked-password reuse works at scale. Note whether either control exists.
- Password policy — can you set
password or 123456? A weak policy undermines everything else.
- Password reset flow — the most-abused recovery path. Check: is the reset token long, random, and single-use? Does it expire? Can you request a reset for another user and have the link leak (host-header poisoning, token in referrer)? Can you reuse an old token?
- Default/weak credentials on admin panels and appliances — try the vendor defaults.
- Session after login — confirm the session ID rotates at login (fixation) and that logout invalidates it (covered in the session-management skill).
Cheatsheet
valid user -> "incorrect password"
invalid user -> "user not found" # <- leak (message, status, or timing)
hydra -l admin -P passwords.txt app.tld http-post-form \
"/login:user=^USER^&pass=^PASS^:Invalid"
- token: long, random, single-use, expiring?
- reset for victim -> does link leak via Host header / referrer?
- old token still valid after use or new request?
admin:admin admin:password root:root (and vendor defaults)
Reading the output
- Distinct valid/invalid responses (text, code, or timing) = username enumeration; it turns password spraying into a targeted attack.
- No lockout/rate limit after many failures = brute force and credential stuffing are open. High impact combined with a weak policy.
- A reset token that's guessable, long-lived, or reusable = account takeover via the recovery flow — often the softest part of auth.
- A reset link that honours an attacker-controlled Host header = poisoned reset emails pointing at the attacker's server.
- Default credentials working = immediate compromise; report as critical.
The fix
- Uniform responses. Same message and similar timing whether or not the account exists, on login, registration, and reset. Don't confirm account existence.
- Rate limit and lock out. Throttle failed logins per-account and per-IP, add CAPTCHA or exponential backoff, and alert on spikes. This blunts brute force and stuffing.
- Strong password policy aligned to current guidance (length over arbitrary complexity), and screen against known-breached passwords.
- Add MFA, especially for privileged accounts — it defeats credential stuffing even when passwords leak (see the IAM MFA skill).
- Harden password reset: long random single-use tokens with short expiry, invalidated after use; never build the reset URL from the Host header; don't leak the token in referrers.
- Remove default credentials before anything ships.
Pitfalls
- Enumeration through the reset/registration flow. Teams fix the login message and forget these two leak the same info.
- IP-only rate limiting. Attackers rotate IPs; limit per-account too.
- Reset tokens treated as an afterthought. The recovery flow is often weaker than login and just as powerful. Test it as hard.
- Client-side password policy only. Enforce it server-side; the client check is a courtesy.
References
- OWASP WSTG-ATHN (Authentication Testing)
- OWASP Authentication Cheat Sheet
- NIST SP 800-63B (Digital Identity — authentication)
- CWE-307, CWE-640 (weak recovery), CWE-521 (weak password requirements)
Inputs
- Relevant source code, logs, network traces, or system specifications.
Outputs
- Analysis findings, security audit report, or generated code artifacts.
1---2name: authentication-testing3description: Use when testing how an app handles login, credentials, lockout, and password reset — the weaknesses that let an attacker log in as someone else — and the fixes.4---5678## Prerequisites9- Target system, dependencies and environment configured.1011## Usage12### Purpose1314Authentication is the front door. Weaknesses here — no lockout, username enumeration, a broken reset flow — hand attackers accounts without any clever exploit. This skill covers testing the login and account-recovery surface and closing the common gaps.1516### When to use it1718Any app with user accounts. Test it early: auth flaws are high-impact and often shallow, so they're a fast source of real findings.1920Test only accounts and apps you're authorised to. Credential attacks against systems you don't own are unauthorised access.2122### Procedure23241. **Username enumeration** — does the app reveal whether an account exists? Compare responses for a valid vs invalid username on login, registration, and password reset. Different error text, different status, or different timing all leak it:25 ```26 "No such user" vs "Wrong password" -> enumeration27 ```282. **Brute force / lockout** — try several bad passwords for one account. Is there a lockout, rate limit, or CAPTCHA after a few failures? If not, the account is brute-forceable:29 ```30 ffuf -w passwords.txt -X POST -d 'user=admin&pass=FUZZ' -u https://app.tld/login -fr 'Invalid'31 ```323. **Credential stuffing exposure** — no rate limiting plus no MFA means leaked-password reuse works at scale. Note whether either control exists.334. **Password policy** — can you set `password` or `123456`? A weak policy undermines everything else.345. **Password reset flow** — the most-abused recovery path. Check: is the reset token long, random, and single-use? Does it expire? Can you request a reset for another user and have the link leak (host-header poisoning, token in referrer)? Can you reuse an old token?356. **Default/weak credentials** on admin panels and appliances — try the vendor defaults.367. **Session after login** — confirm the session ID rotates at login (fixation) and that logout invalidates it (covered in the session-management skill).3738### Cheatsheet3940```bash41valid user -> "incorrect password"42invalid user -> "user not found" # <- leak (message, status, or timing)4344hydra -l admin -P passwords.txt app.tld http-post-form \45 "/login:user=^USER^&pass=^PASS^:Invalid"4647- token: long, random, single-use, expiring?48- reset for victim -> does link leak via Host header / referrer?49- old token still valid after use or new request?5051admin:admin admin:password root:root (and vendor defaults)52```5354### Reading the output5556- **Distinct valid/invalid responses** (text, code, or timing) = username enumeration; it turns password spraying into a targeted attack.57- **No lockout/rate limit after many failures** = brute force and credential stuffing are open. High impact combined with a weak policy.58- **A reset token that's guessable, long-lived, or reusable** = account takeover via the recovery flow — often the softest part of auth.59- **A reset link that honours an attacker-controlled Host header** = poisoned reset emails pointing at the attacker's server.60- **Default credentials working** = immediate compromise; report as critical.6162### The fix6364- **Uniform responses.** Same message and similar timing whether or not the account exists, on login, registration, and reset. Don't confirm account existence.65- **Rate limit and lock out.** Throttle failed logins per-account and per-IP, add CAPTCHA or exponential backoff, and alert on spikes. This blunts brute force and stuffing.66- **Strong password policy** aligned to current guidance (length over arbitrary complexity), and screen against known-breached passwords.67- **Add MFA**, especially for privileged accounts — it defeats credential stuffing even when passwords leak (see the IAM MFA skill).68- **Harden password reset:** long random single-use tokens with short expiry, invalidated after use; never build the reset URL from the Host header; don't leak the token in referrers.69- **Remove default credentials** before anything ships.7071### Pitfalls7273- **Enumeration through the reset/registration flow.** Teams fix the login message and forget these two leak the same info.74- **IP-only rate limiting.** Attackers rotate IPs; limit per-account too.75- **Reset tokens treated as an afterthought.** The recovery flow is often weaker than login and just as powerful. Test it as hard.76- **Client-side password policy only.** Enforce it server-side; the client check is a courtesy.7778### References7980- OWASP WSTG-ATHN (Authentication Testing)81- OWASP Authentication Cheat Sheet82- NIST SP 800-63B (Digital Identity — authentication)83- CWE-307, CWE-640 (weak recovery), CWE-521 (weak password requirements)8485## Inputs86- Relevant source code, logs, network traces, or system specifications.8788## Outputs89- Analysis findings, security audit report, or generated code artifacts.