On this page
How to Prevent Credential Stuffing Attacks
Stop credential stuffing with multi-factor authentication, rate limiting, breached-password detection, and bot detection. Practical steps for any web app.
Quick answer
- Credential stuffing uses leaked username/password pairs from other breaches to break into accounts on your site.
- The three most effective defenses: require MFA, block known-breached passwords, and rate-limit login attempts.
- These protections are additive — one alone reduces risk, all three together make credential stuffing impractical.
What is credential stuffing and why is it different from brute force?
A brute force attack guesses random passwords against a single account. Credential stuffing uses real, known passwords from other breaches — the attacker has the username and a list of passwords the user has used elsewhere. Because password reuse is widespread (roughly half of users reuse passwords across sites), credential stuffing has a far higher success rate than brute force. The attacker doesn’t need to crack anything; they just replay what’s already known.
How does multi-factor authentication stop credential stuffing?
MFA is the strongest defense because even with a valid password, the attacker can’t complete the second factor. TOTP codes, passkeys, and hardware security keys all block credential stuffing regardless of how good the password list is. The gap: if you don’t require MFA for all accounts by default, attackers will target the accounts that haven’t enrolled. The policy that matters is not ‘MFA is offered’ but ‘MFA is enforced for every login from a new device or location.’
How do I block known-breached passwords?
Check passwords at registration and login against a database of credentials exposed in past breaches. The Have I Been Pwned k-Anonymity API lets you check a password hash range without sending the full password. On registration, reject passwords that appear in breach data. On login, flag accounts using breached credentials and force a password reset. This catches credential stuffing where the password matches a known leak, even if MFA isn’t enabled for that account.
# Check a password against HIBP's k-anonymity API (range endpoint)
import hashlib, requests
def is_password_pwned(password: str) -> bool:
sha1 = hashlib.sha1(password.encode()).hexdigest().upper()
prefix, suffix = sha1[:5], sha1[5:]
resp = requests.get(f"https://api.pwnedpasswords.com/range/{prefix}")
return suffix in resp.text
# Use: reject registration or force reset if is_password_pwned(password)Where this bites vibecoders
AI assistants generate login pages readily but almost never add credential-stuffing protections — no rate limiting on login, no breached-password check, no MFA enforcement. The app ships and looks functional until a credential-stuffing bot finds it through a search engine, runs through a million known passwords, and compromises every account that reused a password. Adding rate limiting, breached-password checks, and MFA enforcement in your auth stack closes three of the highest-impact gaps an AI-generated app ships with.
Where AI coding assistants get this wrong
- Generating login pages with no rate limiting, allowing unlimited password attempts.
- No breached-password check at registration, so users sign up with passwords already in leak databases.
- Skipping MFA entirely or making it optional, which means zero accounts have it enabled.
- No account lockout or progressive delay, making credential stuffing fast and undetectable.
Checklist
- Rate-limit login attempts per IP, per account, and globally.
- Require MFA for all accounts, not just as an opt-in.
- Check passwords against breach databases at registration and force resets on detected reuse.
- Add bot detection (CAPTCHA or behavioral) on the login endpoint.
FAQ
What is the difference between credential stuffing and password spraying?
Credential stuffing uses many passwords against many accounts — pairs from a breach. Password spraying uses a few common passwords (like ‘Winter2024!’) against many accounts to avoid lockout thresholds. Both exploit password reuse, and the same defenses (MFA, breached-password checks, rate limiting) stop both.
Does rate limiting alone stop credential stuffing?
It slows it down but doesn’t stop it. Sophisticated attackers distribute attempts across thousands of IPs (botnets, residential proxies) to evade per-IP limits. Rate limiting is one layer in a defense that must also include MFA and breached-password detection to be effective.
Related topics
- What Is Credential Stuffing (and How Does It Get Your Accounts)?
- What Is Phishing-Resistant MFA?
- What Is Rate Limiting?
- How to Add Rate Limiting to an API
- JWT Security: Common Mistakes That Get Tokens Stolen