# Credential stuffing attack succeeds because rate limiting is bypassed by rotating IP addresses

- **ID:** `security/credential-stuffing-via-rate-limit-bypass`
- **Domain:** security
- **Category:** auth_error
- **Error Code:** `AUTH_RATE_003`
- **Verification:** ai_generated
- **Fix Rate:** 75%

## Root Cause

Rate limiting based solely on IP address is ineffective against credential stuffing attacks that use a distributed botnet with many unique IPs, allowing unlimited login attempts.

## Version Compatibility

| Version | Status | Introduced | Deprecated |
|---------|--------|------------|------------|
| Nginx 1.24 | active | — | — |
| Cloudflare WAF | active | — | — |
| AWS WAF | active | — | — |

## Workarounds

1. **Implement multi-factor rate limiting: combine IP, user-agent, and device fingerprint. Use a sliding window with exponential backoff. Example in Nginx:
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
limit_req_zone $http_user_agent zone=ua:10m rate=10r/m;
server {
    location /login {
        limit_req zone=login burst=10 nodelay;
        limit_req zone=ua burst=20 nodelay;
    }
}** (80% success)
   ```
   Implement multi-factor rate limiting: combine IP, user-agent, and device fingerprint. Use a sliding window with exponential backoff. Example in Nginx:
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
limit_req_zone $http_user_agent zone=ua:10m rate=10r/m;
server {
    location /login {
        limit_req zone=login burst=10 nodelay;
        limit_req zone=ua burst=20 nodelay;
    }
}
   ```
2. **Deploy CAPTCHA (e.g., reCAPTCHA v3) after a few failed attempts from the same account or device fingerprint, not just IP.** (90% success)
   ```
   Deploy CAPTCHA (e.g., reCAPTCHA v3) after a few failed attempts from the same account or device fingerprint, not just IP.
   ```
3. **Use account lockout (temporary, e.g., 1 minute) after 5 failed attempts per username, regardless of IP.** (85% success)
   ```
   Use account lockout (temporary, e.g., 1 minute) after 5 failed attempts per username, regardless of IP.
   ```

## Dead Ends

- **Increase the rate limit threshold to allow more requests per IP** — This makes the attack easier because attackers can send more requests per IP, and the distributed nature still bypasses IP-based limits. (95% fail)
- **Block IPs after a few failed attempts with a permanent ban** — Attackers rotate IPs; permanent bans on individual IPs don't stop the attack and may block legitimate users behind shared IPs (e.g., VPNs). (80% fail)
