When per-IP limits stop being enough
A rate limit keyed on IP address sounds like solid protection against brute force and API abuse, yet attackers routinely bypass it through IP rotation, distributed botnets and forged headers. We walk through the common bypass techniques and the more robust countermeasures that key on user accounts instead of raw IP addresses.
Table of Contents
- 1. Why Pure IP-Based Rate Limiting Falls Short
- 2. IP Rotation: Residential Proxies and Cloud IP Pools
- 3. X-Forwarded-For and Friends: Manipulating Identification Headers
- 4. Distributed Botnets: When Thousands of Sources Coordinate an Attack
- 5. Slow Rate Attacks: Staying Below the Detection Threshold
- 6. User Account Instead of IP: More Robust Identification Strategies
- 7. Layered Rate Limiting: Combining Edge, Application and Endpoint
- 8. Adaptive Approaches: Sliding Window, Token Bucket and Behavioral Analysis
- 9. Monitoring, Alerting and the Limits of Any Rate Limiting Strategy
- 10. Summary
- 11. FAQ
1. Why Pure IP-Based Rate Limiting Falls Short
Rate limiting is one of the first defenses developers reach for against brute force attacks, scraping and API abuse. The classic implementation caps the number of requests per IP address within a time window, for example one hundred requests per minute. That works well against a single, uncoordinated script sending naively from one address, but it breaks down quickly once an attacker controls more than one IP address or deliberately tries to dodge the counter.
The core assumption, that an IP address reliably maps to one user or attacker, does not hold in practice. Hundreds of legitimate users often share a single IP behind a corporate NAT or mobile carrier gateway, while a single attacker can obtain dozens of fresh addresses within seconds through cloud providers, proxy networks or compromised devices. Any serious rate limiting design has to assume from the start that IP addresses are an unreliable identifier and pull in additional signals.
2. IP Rotation: Residential Proxies and Cloud IP Pools
The simplest bypass technique is IP rotation. Attackers rent access to pools of thousands of residential IP addresses from commercial proxy providers, addresses that originate from real home connections and are therefore nearly indistinguishable from normal user traffic. Every request, or every small batch of requests, travels through a different address, so the classic per-IP counter never approaches its limit even though the combined traffic targets a single victim.
Cloud providers offer a cheaper, though more easily detected, variant: autoscaling groups with rotating public IP addresses from well-known data center ranges. Those can be blocked more reliably through IP reputation databases and ASN lists, because data center IP ranges are publicly documented. Filtering incoming traffic by source ASN and applying stricter limits to data center ranges on sensitive endpoints removes much of the effectiveness of this cheaper rotation approach.
3. X-Forwarded-For and Friends: Manipulating Identification Headers
Many applications determine the client IP not from the raw TCP connection but from HTTP headers such as X-Forwarded-For or X-Real-IP, because they sit behind a load balancer or reverse proxy. Those headers are set by the client and can be forged freely unless the application configures exactly which upstream proxy it is willing to trust. An attacker who submits a random value in X-Forwarded-For on every request appears to the application as a brand new IP each time, even though the actual TCP connection originates from the same source.
The fix is a strict trust boundary: only the immediate, known reverse proxy should be allowed to set X-Forwarded-For, and the application should only accept it from that single trusted source. On nginx as the entry point, this can be configured cleanly with set_real_ip_from combined with real_ip_header, so forged headers sent by the client itself are discarded and only the value determined by the proxy actually counts.
# nginx.conf: trust only the real upstream proxy
set_real_ip_from 10.0.0.0/8; # internal load balancer network
set_real_ip_from 173.245.48.0/20; # e.g. CDN provider range
real_ip_header X-Forwarded-For;
real_ip_recursive on;
# Only AFTER the real_ip config is $binary_remote_addr trustworthy
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=60r/m;
server {
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
proxy_pass http://backend;
}
}
4. Distributed Botnets: When Thousands of Sources Coordinate an Attack
The most thorough form of IP rotation comes from botnets built from compromised IoT devices, hijacked servers or infected end user machines. A single botnet can easily consist of tens of thousands of devices, so even a very low limit per IP produces an enormous combined attack volume without any single source ever standing out. Login forms are a favorite target because credential stuffing attacks thrive on exactly this distribution: each IP tries only a handful of combinations, yet the overall system tests millions of stolen credentials.
Against a real botnet, plain rate limiting stops helping, because the distribution is specifically designed to stay under every individual limit. What actually works are global aggregation metrics, for example the total number of failed logins across all sources for one affected account, combined with behavioral signals such as missing browser-typical headers, unusual user agent patterns, or the absence of JavaScript execution that separates a headless script from a real browser.
5. Slow Rate Attacks: Staying Below the Detection Threshold
Beyond spreading across many sources, experienced attackers also exploit the time dimension. Instead of hammering an endpoint aggressively in a short window, they spread requests over hours or days and stay deliberately below any threshold that a typical rate limiting rule would trigger. An attacker sending only one request every two minutes per IP evades practically every standard limit, even though the same overall goal now takes considerably longer to reach.
Diversifying across multiple endpoints belongs in the same category: instead of attacking only the login endpoint, traffic also spreads to password reset, registration or API search functions, each of which usually carries its own, often more generous limit. Central monitoring that aggregates requests per user account or target resource across multiple endpoints, rather than looking at each endpoint in isolation, exposes these patterns far more reliably than isolated per-endpoint limits.
6. User Account Instead of IP: More Robust Identification Strategies
The most effective lever against IP-based evasion is shifting the primary identification layer. Instead of counting exclusively by IP address, a limit should also key on the actual target, the user account being attacked. Five failed login attempts for the same username within ten minutes should trigger a lockout or a CAPTCHA regardless of how many different IP addresses are behind them, because the asset worth protecting is the account, not the network address.
This strategy has its own pitfalls: relying purely on account lockout after failed attempts opens the door to denial of service attacks against individual accounts, where an attacker deliberately locks a victim's username with wrong credentials. Robust implementations therefore combine account-based limits with progressive delays instead of hard lockouts, growing wait times between attempts, plus additional IP-based limits as a second, independent line of defense.
7. Layered Rate Limiting: Combining Edge, Application and Endpoint
The most robust architecture combines several rate limiting layers, each covering a different attack pattern. At the edge, in a CDN or WAF, coarse but very fast limits stop obvious mass attacks before every request ever reaches the application. At the application layer, finer, context-aware limits key on user account, session or API key, reacting far more precisely than the coarse edge filtering can.
Endpoint-specific limits form the third layer: a login form naturally tolerates a much stricter limit than a public product search, and an expensive API endpoint that triggers a database aggregation needs a tighter budget than a simple, cached read. Only the interplay of all three layers, coarse and fast at the edge, account-aware in the application, granular per endpoint, makes it economically unattractive for an attacker to bypass any single layer.
8. Adaptive Approaches: Sliding Window, Token Bucket and Behavioral Analysis
Fixed time window counters have a well-known weakness at the window boundary: an attacker can exhaust the full limit right before a minute window ends and again right after, doubling the effective number of requests possible in a short span compared to what was intended. Sliding window algorithms avoid this problem by letting the window continuously slide rather than resetting at hard boundaries, delivering a noticeably smoother, harder to exploit limit.
Token bucket algorithms go one step further and allow controlled bursts while strictly capping the average rate over time. On top of that, a behavioral component pays off by catching anomalies beyond raw counts, for example atypical timing between requests, missing mouse movement on form-based attacks, or request patterns that look machine-timed with mechanical precision rather than humanly irregular.
9. Monitoring, Alerting and the Limits of Any Rate Limiting Strategy
No rate limiting system stays bypass-proof forever, because attackers continuously adapt to new measures. Continuous monitoring that surfaces unusual patterns is therefore essential, for example a sudden spike in failed logins spread across many different IP addresses even though each individual address stays unremarkable. Dashboards that visualize requests per user account rather than only per IP often expose coordinated attacks much earlier than pure IP statistics ever could.
Alerting thresholds should be set so unusual clustering draws attention automatically before an attack causes real economic damage. It also pays to periodically review whether deployed limits still match the current threat picture: a limit that sufficed against simple scripted attacks two years ago can be entirely ineffective against a professionally organized, distributed attack today.
| Bypass Technique | How It Works | Typical Detection | Effective Countermeasure |
|---|---|---|---|
| IP rotation (proxy pools) | Every request through a fresh residential IP | Hard, since IPs belong to real households | Account-based limits instead of raw IP counting |
| Header spoofing | Forged X-Forwarded-For value | Detectable when no proxy trust boundary exists | Trust only the known upstream proxy |
| Distributed botnets | Tens of thousands of devices, few requests each | Only visible through aggregation | Global count per target account, behavioral signals |
| Slow rate attacks | Requests spread over hours, below the threshold | Very hard without long-term monitoring | Cross-window monitoring, sliding window limits |
| Endpoint diversification | Spreading across less-protected endpoints | Only visible across endpoints combined | Central per-user limit across all endpoints |
Mironsoft
Security audits, OWASP-compliant hardening, and secure architecture
Applications that actually hold up against a real attack attempt?
We review existing applications for classic OWASP vulnerabilities, insecure authentication, and missing input validation, then build an architecture that structurally reduces attack surface instead of just patching individual symptoms.
Security Audit
Systematically checking OWASP Top 10, auth flows, and input validation for vulnerabilities.
Secure Architecture
Building rate limiting, encryption, and access controls correctly from the ground up.
Incident Readiness
Establishing logging, monitoring, and response processes for when things go wrong.
10. Summary
Rate Limiting Bypass: The Essentials at a Glance
Core Problem
IP addresses are no longer a reliable identifier.
Most Common Bypass
IP rotation through residential proxy pools and botnets.
Robust Defense
Account-based limits combined with layered rate limiting.
Practical Tip
Only accept X-Forwarded-For from explicitly trusted proxies.