Blog
Credential Security

Why API Credential Stuffing Is Harder to Stop Than You Think

Low-and-slow credential stuffing attacks look like legitimate traffic. Rate limits don't catch them. Here's what behavioral analysis sees that rules miss.

M
Marcus Whitfield
CEO & Co-Founder, Hirefathom
API Credential Stuffing article cover

Credential stuffing is one of the oldest automated attack categories, and it remains one of the most persistently effective. The availability of breached credential datasets — billions of username and password pairs from prior data exposures, circulating on paste sites and private markets — means that attackers have a near-inexhaustible supply of material to test against any authentication endpoint. The question for defenders is not whether credential stuffing is happening against their APIs. It's whether their current controls are actually detecting it.

The honest answer for most engineering teams is: probably not as effectively as you think. The conventional defenses — rate limiting, IP blocking, CAPTCHA — address the high-volume, naive expression of credential stuffing. Modern credential stuffing campaigns have evolved past all three. Understanding why requires looking at how the attacks have changed, not just what they're doing on any individual request.

How Modern Credential Stuffing Campaigns Actually Work

Early-generation credential stuffing tools were blunt: high request volume from a small number of IPs, easily blocked by even basic rate limiting or IP reputation lists. The tools available to attackers today are substantially more sophisticated, and the operational infrastructure behind a serious credential campaign looks nothing like a naive brute-force attack.

Residential proxy networks let attackers route requests through IP addresses belonging to legitimate home ISP subscribers. The IPs are real consumer addresses in real geographies, not datacenter ranges that IP reputation databases flag. Each IP may generate only one or two authentication attempts per hour — well below any per-IP rate limit. The aggregate campaign can test hundreds of thousands of credentials per day while no single source ever exceeds detection thresholds by more than a request or two.

Slow-and-distributed campaigns deliberately spread load across time as well as source IPs. Rather than saturating a target's authentication endpoint over hours, a well-designed campaign runs for days or weeks at low volume. Response time analysis is used to detect when a target is rate-limiting or adding latency, with the campaign backing off and resuming after the cooldown window. The attack adapts to the defense.

Modern credential stuffing tools also support headless browser emulation. Rather than making bare HTTP requests to an authentication endpoint, the tool executes a full browser session — running JavaScript, solving some CAPTCHA challenges, and generating the same TLS fingerprint and header ordering as a legitimate browser. CAPTCHA-solving APIs, both manual farm-based and increasingly automated, are commoditized. Expecting CAPTCHA to provide meaningful protection against a motivated attacker with budget is no longer realistic.

Why Rate Limiting Fails Against Low-and-Slow Attacks

Rate limiting as a credential stuffing defense is based on a simple model: if an IP (or user account) generates authentication failures at high frequency, block or slow that IP. This works against high-volume attacks from concentrated sources. It fails against distributed, paced campaigns because the rate limit is never locally triggered, even when the global attack volume is very high.

Consider the math. A per-IP rate limit of 10 failed authentication attempts per minute is a common configuration. If an attacker has 2,000 IP addresses in rotation, each limited to 9 attempts per minute, the campaign delivers 18,000 authentication attempts per minute against your endpoint — 1.08 million per hour. The success rate on credential stuffing with a large, curated breached credential list against a typical consumer service runs in the low single-digit percentage range for partial matches and lower for valid credential reuse. Even a 0.1% success rate on 1 million attempts yields 1,000 compromised accounts per hour. No per-IP rate limit fires. Every request looks like a single occasional login attempt from a different user.

OWASP's Testing Guide for Authentication (WSTG-ATHN-03) and the API Security Top 10 2023 both note that distributed, throttled attacks require statistical detection approaches rather than threshold-based blocking. This isn't a new observation — it's an operational reality that most rate-limit configurations simply don't address.

What Behavioral Analysis Sees That Rules Miss

Behavioral detection of credential stuffing doesn't look at any single request. It looks at the population of requests to your authentication endpoints over time and across source diversity, and builds a model of what normal authentication traffic looks like for your specific API. Several signals are distinctive in credential stuffing campaigns even when individual requests appear legitimate:

Authentication failure rate distribution. A normal user population exhibits a failure rate in the 3–8% range — people mistype passwords, use the wrong account, forget which email address they registered with. A credential stuffing campaign running against a typical breached credential list will exhibit failure rates of 90–99%+ across the campaign IP pool. This signal is invisible per-IP but clear in the aggregate. If your authentication endpoint's overall failure rate jumps from 5% to 40%, something changed — and it's almost certainly not your users forgetting their passwords.

Session continuation patterns. After a legitimate successful login, users navigate — they call other endpoints, view account data, take actions. After a credential stuffing tool succeeds, the pattern is typically either immediate session exfiltration (account takeover with rapid profile/payment data access) or no continuation at all (the tool records the successful credential pair and moves on without taking further action on that session). Successful authentications that don't generate any subsequent API activity are anomalous and signal credential validation without legitimate user presence.

Credential reuse across endpoints. Sophisticated campaigns test the same credentials against multiple authentication endpoints — web login, mobile app auth, API key endpoints, password reset flows. A credential that appears across requests to /api/v1/auth/login, /api/mobile/v2/signin, and /api/partner/token within a short timeframe from different IPs is a strong signal for credential testing, not legitimate multi-device user behavior.

Geographic and temporal coherence. A user who authenticates from Chicago at 10 AM and then shows a login attempt from Singapore at 10:15 AM (impossible travel) is a well-known signal. Less commonly implemented: detecting credential testing that systematically rotates through geographically diverse IPs in a pattern consistent with proxy pool rotation rather than genuine user mobility.

A Scenario: Three Weeks Undetected

Consider a growing marketplace platform — call it Helix Market — running a B2B procurement API. Their POST /api/auth/session endpoint handles authentication for supplier and buyer accounts. Rate limiting is configured at 15 requests per IP per minute. IP reputation blocking is active. The platform has been running without significant security incidents for 18 months.

Beginning on a Monday in a typical operational quarter, authentication failure rates on that endpoint start climbing — slowly, from a baseline of roughly 6% to 12% over the first week, reaching 28% by the end of week two. No per-IP threshold fires. The IPs are all residential, geo-distributed across four countries. Individual request headers and TLS fingerprints look like real browsers. CAPTCHA challenges appear on 15% of requests and are solved correctly.

At week three, three supplier accounts are reported as having orders placed without their authorization. Investigation confirms account takeover — the credentials were in a breach database from an unrelated service. Total campaign duration before detection: 21 days. The signal was in the failure rate distribution the entire time; there was simply no monitoring system aggregating authentication outcomes across the full IP population and comparing them against baseline.

This isn't a contrived example. It describes the operational profile of real credential stuffing campaigns as observed across mid-market B2B platforms. The attack works because it's designed to stay below the resolution of threshold-based monitoring.

Defenses That Actually Work Against Modern Campaigns

We're not saying rate limiting and IP blocking are worthless — they filter out the unsophisticated attacks that make up a significant percentage of total credential stuffing volume. Eliminating that noise has operational value. But stopping there leaves the more capable campaigns running undisturbed.

Effective defenses against modern credential stuffing require two things that rules-based controls don't provide: population-level statistical monitoring (aggregate failure rates, session continuation patterns, cross-endpoint credential correlation), and per-entity behavioral context (what does this specific credential's authentication history look like, across time and across source IPs?). These capabilities require maintaining state and building behavioral models, not just matching individual requests against threshold conditions.

Combining device fingerprinting signals (consistent TLS fingerprint, browser entropy, header ordering) with behavioral context substantially raises the cost for attackers. A campaign that previously needed to rotate 2,000 IPs to avoid rate limits now needs to also rotate device fingerprints convincingly — a much harder operational challenge. Requiring step-up authentication on sessions that show anomalous post-login behavior (no navigation activity, immediate access of sensitive account fields) catches account takeovers in the window between initial access and fraud.

The credential stuffing problem isn't going away. The supply of breached credentials is effectively unlimited. The tooling available to attackers continues to evolve. Defenses that were adequate in 2018 are inadequate against campaigns running in 2025 and beyond — and the gap between what organizations think their rate limits are catching and what's actually running against their authentication endpoints is often larger than they realize.