Credential stuffing
Credential stuffing is an attack in which someone replays username and password pairs stolen from other services against your login, betting that people reuse passwords. Nothing is guessed and nothing is cracked: every attempt uses a credential that was correct somewhere else, which is why the success rate is low and the volume enormous.
How it works
The input is a list of pairs, not a wordlist. It comes from breach corpora traded and republished over years, and increasingly from infostealer logs, which are different and more dangerous: those are credentials taken from a browser on an infected machine, so they are current, they include the exact site each one belongs to, and they often come with the session cookies as well.
The attacker automates the login, distributes the requests across residential proxies so the source addresses look like ordinary customers, rotates user agents, and paces the attempts so that no single account or address stands out. Where an API endpoint accepts credentials without the browser checks the web form applies, that endpoint is used instead. Mobile application back ends and legacy authentication paths are the usual choices.
The economics work because of scale and reuse. The proportion of pairs that succeed is small. The list is very large, the cost per attempt is close to zero, and a successful account is immediately worth something: stored payment details, loyalty balances, order history for a convincing follow-up call, or a mailbox from which to run business email compromise.
What follows a success is usually not immediate abuse. The account is validated, sorted and sold. The gap between takeover and use is why the login event and the fraud event are often weeks apart in the logs, and why teams investigating the fraud never look back far enough to find the cause.
What goes wrong
The defence that fails most reliably is account lockout, because it is a control aimed at a different attack. Stuffing does not try many passwords against one account; it tries one password against many accounts. Per-account counters never trip. Worse, an attacker who wants to cause damage rather than gain access can use the lockout deliberately, and the helpdesk absorbs the incident.
The second failure is coverage. A team hardens the web login, and the mobile back end, the legacy endpoint, the partner integration and the password reset flow all accept credentials with none of the same protections. On engagements we look for the second door first: it exists in most estates, and it is usually the one with no rate limiting at all.
The third is that everything an attacker needs to blend in is available for hire. Residential proxy networks make address-based blocking close to useless, and services exist to solve the challenges that were supposed to prove humanity. Any control that depends on the request looking wrong is a control with a purchase price attached.
The fourth is the one that decides whether stuffing matters at all: whether the account is worth anything after it is taken. Where a successful login gives immediate access to stored payment details and to a change-of-address function with no re-authentication, one credential is a fraud. Where sensitive actions require a fresh check, the same credential is an alert.
Credential stuffing, password spraying and brute force
The three are grouped as password attacks and defended against as if they were one thing. They have different inputs, different signatures and different countermeasures.
| Credential stuffing | Password spraying | Brute force | |
|---|---|---|---|
| Input | Known valid pairs from elsewhere | A few common passwords, many accounts | Many passwords, one account |
| What it exploits | Password reuse | Predictable password choice | Weak passwords and no throttling |
| Volume per account | One or two attempts | One attempt per round | Very many |
| Trips account lockout | No | Rarely, if paced | Yes, almost immediately |
| Best signal | Failure rate per source, impossible geography | One password against many accounts in a window | Failures against a single account |
| Main countermeasure | Breached-credential checks, origin-bound factors | Long passphrases, monitoring across accounts | Throttling and lockout |
The consequence for a defender is that the three need to be watched at different aggregation levels. Brute force is visible per account. Password spraying is only visible when you count across accounts within a time window. Stuffing is only visible when you count the failure rate per source and per campaign. A monitoring setup that only counts failures per account sees the first and misses the other two entirely.
Common mistakes
Relying on lockout. It does not fire, and it is itself a denial of service primitive.
Blocking by address. Residential proxy pools rotate through legitimate consumer addresses. Blocking by address blocks customers.
Assuming MFA closes it. It closes most of it, and codes and push approvals can still be relayed, and the paths that do not enforce it are where the attack goes. Enforcement coverage matters more than the factor.
Enforcing complexity rules instead of checking reuse. Rules push users towards predictable transformations. Checking a proposed password against a breached-credential corpus addresses the actual mechanism.
Not telling the user. A notification of a login from a new device, and of a change to email or payment details, converts a silent takeover into a customer support call, which is a far better outcome than a chargeback.
How to detect and reduce it
Check credentials against known-breached corpora at registration, at password change and, where the platform allows it, periodically for existing accounts. This attacks the mechanism directly rather than its symptoms. Where an account’s credential is known to be exposed, force a change rather than recording a risk score.
Deploy origin-bound factors on the accounts that hold value, and make the enforcement uniform across every authentication path, including mobile back ends and any legacy endpoint. An estate with strong authentication on the website and a bare API is not protected.
Then make the account worth less. Re-authenticate before changing email, phone number, payment details or delivery address, and notify the user out of band when any of them change. Most of the loss from a takeover comes from those four operations, and gating them individually is cheap.
Apply rate limiting at the campaign level rather than per account: failure rate per source, per address range, per device fingerprint, per user agent. And watch for the shape of a stuffing run rather than for volume alone. The clearest signal is an unusual ratio, thousands of attempts with a failure rate near total, distributed thinly enough that no single counter fires. That ratio is not what normal traffic looks like.
Where this shows up in an audit
We test the authentication surface rather than run a live stuffing campaign against production. The questions are which endpoints accept credentials, what protections each one applies, whether the responses distinguish a valid username from an invalid one, and what a successful login reaches before any further check.
The evidence is the request and response for each path, including the timing and message differences that allow account enumeration, and a demonstration of what a session obtained with a valid credential can do without re-authenticating. Where we use exposed credentials belonging to the client, they come from monitoring work the client has commissioned, they are handled under the engagement rules, and they are not reproduced in the report.
Severity is written against consequence, not against the presence of a login form. Missing rate limiting on an endpoint with strong factors and re-authentication on sensitive actions is a moderate finding. The same gap where a session immediately exposes payment details is a serious one.
Exposure of the credentials themselves is a different question, and it is what monitoring for leaked credentials belonging to the organisation answers: whether your users’ pairs are already in the lists being replayed.
FAQ
How is credential stuffing different from brute force? Brute force guesses passwords for an account. Credential stuffing does not guess: every pair it tries was valid on some other service. That is why it needs one attempt per account, why lockout does not catch it, and why the fix is about reuse rather than about password strength.
Does MFA stop credential stuffing? It stops the takeover on any path where it is enforced, which is the largest single improvement available. It does not stop the attempts, it does not help on paths where it is not enforced, and codes and push approvals can still be relayed by a phishing proxy.
Where do the credential lists come from? Historic breach corpora that circulate and get recombined, and infostealer logs from infected machines. The second kind is more damaging because the credentials are current and are labelled with the exact service they belong to.
Can we detect it if the attacker is slow and distributed? Not by per-account counters. You detect it by aggregating: failure rate per source and per range, sudden appearance of many first-time devices, and successful logins with no preceding session history. Detection at the campaign level is the only level where the pattern exists.