Attackers don't guess passwords — they replay millions of real ones leaked from somewhere else.
People reuse passwords. When one site leaks its password database, that list of email:password pairs gets traded and replayed against every other site. The attacker isn't brute-forcing one account — they're trying known-good credentials against your login, betting that some fraction of your users reused theirs.
Credential stuffing is high-volume, low-per-account, and uses valid passwords, so it sails past naive "wrong password" defenses. The hits convert directly into account takeover. Defense is about raising the cost per attempt — rate limits, bot detection, and a second factor the attacker can't replay.
The failure mode: a login endpoint that treats every request the same, with no per-IP / per-account throttle and only a password as proof. Valid leaked credentials slip through and the only signal is a quiet spike in successful logins from new devices.
The fix is layered. Throttle attempts, fingerprint bots, and require a factor the attacker doesn't have. Below, a successful password check is necessary but not sufficient — a step-up factor gates the session.
def login(email, password, ctx):
# 1. Throttle BEFORE doing expensive work — per IP and per account.
if rate_limiter.too_many(ctx.ip) or rate_limiter.too_many(email):
raise TooManyAttempts() # 429, with backoff
# 2. Constant-time check; never reveal "user exists" vs "wrong password".
user = users.get(email)
if not user or not verify_password(password, user.hash):
audit("login.failed", email, ctx.ip)
raise InvalidCredentials() # same message either way
# 3. Password is necessary, not sufficient. Step up when risk is high.
if risk_engine.is_suspicious(ctx) or user.mfa_enabled:
return require_second_factor(user) # TOTP / passkey / push
return issue_session(user)
| Signal | What credential stuffing looks like |
|---|---|
| Login volume | Sharp spike in total attempts from many IPs |
| Failure rate | Very high failure ratio (most pairs don't match) |
| Success pattern | Successes from new devices / new geographies |
| User agent | Headless / scripted clients, rotating proxies |
| Account spread | One attempt each across thousands of accounts |
An attacker buys a list of 2,000,000 email:password pairs leaked from an unrelated forum and replays them against your login. Suppose 0.5% of your users reused those exact passwords. With no throttle, that's ~10,000 instant account takeovers in minutes.
Add a per-account limit of 5 attempts per hour and the attacker still gets one shot per account — so add bot detection on the IP spike, and require MFA on logins from unrecognized devices. Now a correct password from a new device lands on a second-factor wall the attacker can't clear, and the 10,000 takeovers collapse toward zero while the spike trips your alerts.
Your login spike is mostly failed attempts, but a handful succeed from brand-new devices. What's the highest-leverage fix?
Coach note: a correct password is the attacker's starting point here, not their obstacle — so the leverage is in the layer after the password, not the password itself.