{"id":"hunt-forgot-password","name":"hunt-forgot-password","summary":"Hunt Forgot Password / Account Recovery 認証の欠陥 — 5つの明確なパターン:(1) 有効なメールと無効なメールの異なる応答によるユーザー名列挙、(2) API応答本体で直接公開されたトークンリセット、(3) 使用後に無効化されないリセットトークン(リプレイ)、(4) パスワー…","body":"## Autonomous Testing Priority\n\n**Start with username enumeration — it's the fastest win and gates the rest.**\n\n**Pattern 1 — Username enumeration (response difference for valid vs invalid email):**\n1. POST to the forgot-password endpoint with a clearly invalid email (e.g. `nonexistent@fakedomain12345.com`) — record the response body, status code, and length\n2. POST with an email you know exists (or try common patterns like `admin@target.com`, `test@target.com`, `user@target.com`)\n3. Compare responses: different message (\"Email sent\" vs \"Email not found\"), different HTTP status, or meaningfully different body length = username enumeration confirmed\n4. Proof: enumeration is confirmed when the two responses differ measurably (baseline vs probe) in message text, status code, or body length\n\n**Pattern 2 — Reset token exposed in the API response:**\nSome APIs return the reset token directly in the response body (instead of only emailing it). POST to the forgot-password endpoint and look for a token, link, or code in the JSON/HTML response. If a token appears that lets you reset the password, that's an immediate account-takeover vector.\n\n**Pattern 3 — Reset token replay (reuse after use):**\n1. Complete a full password reset cycle: request token → use it to reset password\n2. Immediately try submitting the same token again to the reset-password endpoint\n3. If the second submission returns 200 or \"success\" → token not invalidated after use\n\n**Pattern 4 — No rate limit on reset requests:**\nSubmit the forgot-password endpoint 10-20 times rapidly with the same email. If all succeed without a 429, lockout, or CAPTCHA → no rate limit (enumeration + token flooding is possible).\n\n**Content-type:** Forgot-password endpoints are often JSON-based REST APIs. Use `application/x-www-form-urlencoded` only if the endpoint is a traditional HTML form (check the login page's HTML to determine form encoding).\n\n**Proof:** Username enumeration = measurably different response (body/status/length). Token exposure = token in response body. Token replay = second successful use of a consumed token.\n\n---\n\n## Vulnerability Classes in This Skill\n\n### 1. Username Enumeration via Password Reset\nDifferent error messages for valid vs invalid accounts leaks the user list without authentication. Even timing differences (fast \"no user found\" vs slow \"email queued\") count.\n\nHigh-value targets: admin accounts, employee email patterns, API keys derived from usernames.\n\n### 2. Weak / Predictable Reset Tokens\nA reset token derived from timestamp, username, or sequential IDs can be brute-forced:\n- `base64(email + timestamp)` — decodable\n- 4-6 digit numeric code — 10K guesses, easily feasible with no rate limit\n- Sequential `token=1234`, `token=1235` — trivially enumerable\n\n### 3. Token Not Bound to Session or IP\nMost apps generate a token, email it, and accept it from any browser. A truly bound token should only work from the same IP or require the original session cookie. If neither is enforced → link forwarding = account takeover.\n\n### 4. Reset Link Doesn't Expire\nCommon best practice: reset tokens expire within ~15–60 minutes (no hard RFC mandates the exact value; OWASP recommends a short, single-use lifetime). If a token from 24 hours ago still works → persistence risk for phishing attacks.\n\n### 5. No Rate Limit on Reset Endpoint\nAn uncapped reset endpoint enables:\n- Email flooding (DoS against victim's inbox)\n- Token brute-force if the token space is small\n- Username enumeration at scale\n\n---\n\n## Related Skills\n\n- **`hunt-ato`** — owns the account-takeover CHAIN (password-reset is its path #1). This skill finds/proves the recovery-flow primitive; hand off to hunt-ato to assemble the full takeover.\n- **`hunt-cache-poison`** — host-header injection during reset email generation (different vulnerability, same flow)\n- **`hunt-brute-force`** — rate-limit testing pattern applies to the reset endpoint too\n- **`hunt-auth-bypass`** — if the reset flow can be skipped entirely (go to `/reset-password?token=` with empty/null token)\n- **`hunt-mfa-bypass`** — if MFA is required after reset, test the bypass there","author":"@elementalsouls","ownerProfile":null,"authorContacts":null,"sourceUrl":"https://github.com/elementalsouls/Claude-BugHunter/tree/main/skills/hunt-forgot-password","license":"MIT","category":"testing","lang":"en","tokens":918,"stars":0,"calls30d":1,"claimed":false,"visibility":"public","origin":"crawler","version":"0.1.0","createdAt":"2026-08-22","updatedAt":"2026-08-22","files":[],"requires":{"mcp":[],"tools":[]},"safety":{"flags":[],"scannedAt":"2026-08-22","hasScripts":false,"networkEndpoints":[]}}