Credential stuffing is the automated replay of username-password pairs leaked from one service against many others, exploiting password reuse. It is a volume attack: success rates of even a fraction of a percent yield thousands of takeovers at breach-corpus scale, and the login attempts arrive with valid credentials, so password checking alone cannot distinguish them from users.
Because the credentials are valid, the defences that work operate on everything except the password: the rate and distribution of attempts, the device and network they arrive from, and whether the pair appears in a known breach corpus. Checking a credential against breach data before accepting it turns a volume attack into a list the defender also holds.
The attack scales because the inputs are free and the infrastructure is cheap. Breach corpora circulate in the billions of pairs, residential proxy pools distribute attempts across addresses that look like customers, and the attacker needs no success rate worth reporting to profit. Defences framed as blocking bad actors tend to fail here, because the traffic is indistinguishable from users at the level of any single request.
Rate limiting is necessary and insufficient on its own, since distribution defeats per-address limits and a patient attacker simply slows down. The counts that carry signal are aggregate and account-shaped: how many distinct accounts one client touched, how many distinct clients touched one account, and how the failure rate compares to the population. Those are cheap to compute and hard for the attacker to flatten.
The structural fix is to stop having a password to stuff. Where that migration is incomplete, checking a credential against known breach data at set time and at login turns the attacker's list into a list the defender also holds, and the accounts most at risk are the ones where account takeover chains start.
The durable remedy is removing the password from the login path altogether, which is what a passkey does.
Related terms
PasskeyBridge verifies identity signals like these inside the request, with zero PII stored. See how the platform works or test the live API.