Lion Cipher Lab
Defend a Login Against Credential Stuffing
- Identity & Access Management
- Intermediate
- ~90 min
- Free · no account required
Why it matters
Credential stuffing is the most common account-takeover technique on the internet: attackers take the billions of email:password pairs leaked from past breaches and simply try them on your login, because people reuse passwords everywhere. It needs no clever exploit — just your login form and a list. Knowing how to see it happen against your own app, and how to layer the handful of defenses that actually stop it (rate limiting, breach screening, and above all MFA), is core identity-and-access work and one of the most common real-world and interview topics in the field.
What you'll learn
- defining credential stuffing precisely and distinguishing it from brute force — stuffing replays VALID username+password pairs leaked from OTHER sites (few guesses per account, but across millions of accounts), while brute force makes many guesses at ONE account; the two threats call for different defenses
- storing passwords correctly even in a demo (salted one-way hashes via werkzeug/bcrypt, never plaintext) and understanding why hashing does NOT stop stuffing (the attacker already has the plaintext from another breach)
- building a tiny combo list and running an attacker script that POSTs each pair to a login endpoint, then reading the HTTP responses to see exactly which accounts an UNPROTECTED login lets an attacker validate at speed
- adding per-IP AND per-account rate limiting with exponential backoff, and re-running the attack to watch 401s turn into HTTP 429 with Retry-After
- making the key judgment call: why naive per-account lockout ALONE is dangerous (an attacker can lock every real user out of their own account = denial of service), and why NIST prefers throttling + monitoring over aggressive lockout
- screening passwords against breach corpuses with the Have I Been Pwned Pwned Passwords RANGE API using k-anonymity — SHA-1 the password, send only the first 5 hex characters, match the suffix locally, so the full password never leaves your machine
- adding TOTP multi-factor authentication and proving it defeats stuffing even when the stolen password is 100% correct, while a legitimate user with the code still gets in
- explaining which controls actually stop stuffing versus which are friction or theatre, and why 'just require complex passwords' does not help when the reused password IS the leaked one
Steps in this lab
- What credential stuffing is — and how it differs from brute force
- Set up Python, the packages, and the lab folder
- Build the VULNERABLE login app (passwords hashed, but no defenses)
- Make a combo list and an attacker script
- Run the attack against the unprotected login
- Build the hardened app with layered defenses (rate limit + MFA, flag-controlled)
- Layer 1 — rate limiting, and the per-account-lockout trap
- Layer 2 — screen passwords against breaches with HIBP k-anonymity
- Layer 3 — MFA, the control that stops stuffing even with a valid password
- Judgment: what actually stops stuffing, and what is theatre