All writing

Credential stuffing and password spraying, explained for site owners

· 6 min read

Both attacks abuse the same fact: people reuse passwords. Credential stuffing takes billions of leaked email-and-password pairs from other sites' breaches and tries them against yours, on the bet that some of your users reused theirs. Password spraying inverts it — a few very common passwords tried against many accounts, slowly, staying under every per-account limit. Neither looks like anything from a single request. That is the point of them.

Why your rate limiter does not see it

Per-IP limits assume the attacker has one address. Stuffing runs through residential proxy networks — thousands of addresses, each making a handful of attempts, each individually indistinguishable from a guest who forgot their password. Per-account lockouts assume the attacker hammers one account. Spraying touches each account a few times and moves on. Both controls are worth having, and both are blind to the shape of the attack, because the shape only exists in aggregate.

The three patterns that give them away

  • One source failing against many different accounts in a window — spraying. A front desk sharing a terminal fails six times against one account; it does not fail against twelve accounts.
  • One account attacked from many sources — stuffing working through a proxy list toward a target worth having.
  • A success that follows a run of failures, from an address that account has never used before — the takeover itself, and the one that justifies waking somebody up.

None of these requires reading passwords, and none should. The analysis needs only outcomes — success or failure, an account identifier, a source, a time. Hash the account identifier before it leaves your server and the analysis still works while the data becomes worthless to anyone who obtains it, including the vendor doing the analysis. If a security product asks for more than that to detect these attacks, it is asking for more than it needs.

What to do about each

  • Spraying: block or challenge the source, and check whether any account it touched shows a success
  • Stuffing against one account: lock the account, force a reset through a channel the attacker does not hold
  • The success-after-failures pattern: treat it as a live takeover — end the session, reset, and review what that account accessed

PharosHub's guard package reports authentication outcomes with a one-line call — hashed identifiers, never passwords — and the correlation layer watches for exactly these three shapes across every address at once. It is the aggregate view your login form cannot have, delivered without your users' secrets ever leaving your building.