# Unthrottled short verification code brute force

Short OTP or reset code with per-IP-only, non-atomic, or absent attempt limits and no token expiry

_Area: Web authentication and account takeover. Seen in 4 disclosed reports; 3 confirmed bounties, median $500, range $300-$5,000; latest 2025-06-09. Updated 2026-10-24._

## How it works
A short code (4 digits, 4 alphanumerics) is checked against a guessable space. Safety depends on one assumption: the number of guesses an attacker can make is bounded. That bound breaks when the check endpoint has no limit, limits only per IP (rotatable), limits non-atomically (concurrent requests slip past the counter), or issues a token that never expires so guesses accumulate against the same target. The code space is small enough that a few million tries is routine.

## Where it shows up
- Verification endpoints returning distinct success/failure responses (200 vs 401) with no throttle [E3](https://bugbountylibrary.com/r/h1%3A767765.md).
- Per-IP rate limiting as the only defense, with no per-account or per-token counter [E1](https://bugbountylibrary.com/r/blog%3Abrutecat-com-articles-leaking-google-phones.md).
- A per-session login token issued before OTP entry that persists across unlimited attempts [E4](https://bugbountylibrary.com/r/h1%3A766578.md).
- Lockout counters that a separate recovery/unlock flow can reset without its own limit [E2](https://bugbountylibrary.com/r/blog%3Aweb-archive-org-web-20200506144651-https-medium-com-jeppe-b-weikop-2fa-bypass-via-logical-rate-limiting-bypass-25ae2a4e1.md).
- No-JS or fallback paths that skip the anti-abuse check the main path enforces [E1](https://bugbountylibrary.com/r/blog%3Abrutecat-com-articles-leaking-google-phones.md).

## How to review
Find every endpoint that validates a short code. For each, confirm the invariant: total failed attempts against a given account/token are capped by a counter that is atomic (incremented server-side before the comparison, not after) and not resettable by any unthrottled flow. Check that the token or code expires after a fixed number of failures and a fixed time, and that success/failure responses are not distinguishable in a way that speeds guessing. Treat per-IP limits as insufficient alone. For fallback paths, verify they enforce the same anti-abuse proof as the primary path [E1](https://bugbountylibrary.com/r/blog%3Abrutecat-com-articles-leaking-google-phones.md).

## Variants seen
- No rate limit on reset-code endpoint, 4-char alphanumeric code [E3](https://bugbountylibrary.com/r/h1%3A767765.md).
- Non-expiring login token plus 4-digit SMS OTP, no attempt limit [E4](https://bugbountylibrary.com/r/h1%3A766578.md).
- Unlock endpoint with no limit resetting the 2FA lockout indefinitely [E2](https://bugbountylibrary.com/r/blog%3Aweb-archive-org-web-20200506144651-https-medium-com-jeppe-b-weikop-2fa-bypass-via-logical-rate-limiting-bypass-25ae2a4e1.md).
- No-JS recovery form bypassing BotGuard, leaving only per-IP limiting [E1](https://bugbountylibrary.com/r/blog%3Abrutecat-com-articles-leaking-google-phones.md).

## Impact and severity
Full account takeover in all four reports, including high-value accounts [E1](https://bugbountylibrary.com/r/blog%3Abrutecat-com-articles-leaking-google-phones.md)[E3](https://bugbountylibrary.com/r/h1%3A767765.md)[E4](https://bugbountylibrary.com/r/h1%3A766578.md). Severity is driven by code space size, whether the token expires, and whether any per-account counter exists; per-IP-only or resettable limits made it worse [E1](https://bugbountylibrary.com/r/blog%3Abrutecat-com-articles-leaking-google-phones.md)[E2](https://bugbountylibrary.com/r/blog%3Aweb-archive-org-web-20200506144651-https-medium-com-jeppe-b-weikop-2fa-bypass-via-logical-rate-limiting-bypass-25ae2a4e1.md).

## Evidence
- E1: https://bugbountylibrary.com/r/blog%3Abrutecat-com-articles-leaking-google-phones.md
- E2: https://bugbountylibrary.com/r/blog%3Aweb-archive-org-web-20200506144651-https-medium-com-jeppe-b-weikop-2fa-bypass-via-logical-rate-limiting-bypass-25ae2a4e1.md
- E3: https://bugbountylibrary.com/r/h1%3A767765.md
- E4: https://bugbountylibrary.com/r/h1%3A766578.md
