vulnerabilityinvestigative journalistcomparisonvulnox-datapreventiontoolspredictions

API rate limiting bypass: what Vulnox assessments find that scanners miss

Geert WarmenbolGeert WarmenbolApril 29, 2026
Share:
API rate limiting bypass: what Vulnox assessments find that scanners miss

Key takeaways

  • IP-based rate limiting is bypassed by any attacker with access to a residential proxy network — the entry cost for a 10,000-IP rotating proxy pool is under $50/month, making IP-reputation blocking insufficient as a standalone control.

  • In Vulnox assessments, WAF rate limiting covered public-facing API endpoints but left internal service-to-service APIs unscoped in the majority of environments — the attack surface that matters most for lateral movement after initial compromise.

  • Rate limits configured for average legitimate traffic fail during credential stuffing campaigns because attackers deliberately spread requests across accounts, not across time — per-IP thresholds do not detect account enumeration distributed across 50,000 IPs at 1 request each.

  • The OWASP API4:2023 Unrestricted Resource Consumption finding appears in assessments not because rate limiting is absent, but because rate limiting was configured for the load balancer layer and never applied at the application layer where business logic executes.

  • Organizations that test rate limiting with synthetic traffic patterns miss the evasion — effective rate limit validation requires simulating the request distribution patterns of actual credential stuffing toolkits, not uniform high-volume load.

TL;DR

Rate limiting looks solved until you test it the way attackers test it. The configurations that pass internal review and WAF audits fail against distributed credential stuffing, internal API abuse, and application-layer business logic attacks that never exceed per-IP thresholds. The gap is not in knowing that rate limiting matters — it is in the distance between what was configured and what was validated.

The WAF that was configured correctly and protected nothing

A SaaS company with around 150 employees had deployed a cloud WAF in front of their API gateway 18 months before Vulnox ran an assessment. The WAF was properly configured by the team that deployed it: IP-based rate limiting on the authentication endpoint at 20 requests per minute, blanket 429 responses above threshold, and IP reputation blocking enabled. The security team knew the configuration was there. They had tested it by hitting the endpoint from a single IP at 30 requests per minute and confirming that the 429 fired correctly.

During the Vulnox assessment, a simulated credential stuffing scenario distributed 40,000 requests across 8,000 source IPs over a 4-hour window — 5 requests per IP, spread across the authentication and password reset endpoints. The WAF blocked nothing. Every request was below the per-IP threshold. The application received every request and processed every authentication attempt. The rate limit was working exactly as configured. It was configured for the wrong attack model.

The same environment had 14 internal microservice APIs that communicated over a service mesh. None of them had rate limiting. One of those internal APIs accepted account update requests and performed no authorization check beyond validating that the caller was an authenticated internal service — an assumption that held until an internal service was compromised.

Turning point:

The client's belief going in: 'We have WAF rate limiting on all our public endpoints. We tested it and it works.' The actual problem: the test validated the threshold mechanism, not the threat model. Credential stuffing does not attack from a single IP at high volume. It attacks from many IPs at low volume. The entire WAF configuration was validated against a scenario that no realistic attacker would use.

What rate limiting failures actually look like in assessed environments

0 of 9

SaaS and e-commerce clients in a recent Vulnox assessment cohort whose rate limiting configuration had been validated against distributed request patterns — all had tested single-source high-volume scenarios, none had simulated credential stuffing request distribution across multiple source IPs. (Vulnox assessment data, 2024)

Internal APIs unscoped in the majority of assessed environments

Vulnox assessments consistently find that WAF and API gateway rate limiting covers public-facing endpoints. Internal service-to-service APIs operating behind the perimeter — typically microservice communication, admin endpoints, and batch processing APIs — have no rate limiting applied and in many cases no authentication beyond network-layer trust. (Vulnox assessment data, 2024)

Under $50/month

Entry cost for a residential proxy pool of 10,000 rotating IPs from commercial proxy providers as of 2024 — the operational cost that makes IP-based rate limiting insufficient as a standalone control against any moderately resourced attacker. (Commercial proxy provider pricing, 2024)

OWASP API4:2023

Unrestricted Resource Consumption is listed in the OWASP API Security Top 10 specifically because rate limiting failures remain pervasive despite being a well-documented class of vulnerability — the problem is not awareness, it is the gap between configured and validated controls. (OWASP API Security Top 10 2023)

Why IP-based rate limiting fails against the attack patterns that matter

Rate limiting works by counting requests from an identified source and blocking or throttling that source when it exceeds a defined threshold within a time window. The mechanism is sound. The failure is in how 'source' gets defined and how the threshold gets set.

IP-based rate limiting defines source as source IP address. That was a reasonable approximation when attacks came from single hosts or small botnets. The residential proxy market changed that calculation. Commercial proxy services now offer rotating pools of tens of thousands of residential IP addresses — actual consumer broadband connections belonging to devices enrolled in proxy networks through browser extensions, free VPN services, and bundled software. Requests routed through these pools appear to originate from legitimate residential addresses in multiple countries, rotating on a per-request or per-session basis. The IP reputation blocklists that WAFs use to filter known datacenter and proxy IPs do not cover residential proxies because those IPs are legitimately residential — the address is not the problem, the traffic routing service is.

The second failure is threshold calibration. Rate limits are typically set based on observed legitimate traffic peaks: if the highest legitimate usage is 15 requests per minute from a single IP, the threshold gets set at 20 to provide margin. That threshold stops a single aggressive attacker. It does not stop an attacker who distributes 200,000 requests across 50,000 IPs at 4 requests each over 60 minutes. The per-IP count never triggers. The aggregate attack volume against the application is substantial. The rate limiting infrastructure reports zero blocked requests and declares the environment clean.

The third failure is layer mismatch. Rate limiting applied at the WAF or load balancer layer operates on network request counts. Business logic rate limiting — preventing a single account from receiving more than 5 password reset emails per hour, or preventing a single user ID from attempting more than 10 authentication attempts per day regardless of source IP — must be implemented at the application layer. WAF rate limiting and application-layer rate limiting are not substitutes. They address different attack surfaces. Organizations that deploy WAF rate limiting and consider the problem solved have addressed network-layer volume attacks and left application-layer abuse entirely open.

Example

A fintech client assessed by Vulnox had correctly implemented IP-based rate limiting on their authentication endpoint at the API gateway. Their password reset endpoint had a separate limit. Their account enumeration exposure came from a third endpoint: a 'check if email exists' pre-validation call used in their registration flow to provide inline feedback before form submission. That endpoint had no rate limiting because it was not an authentication endpoint. It returned a boolean. An attacker could enumerate the entire customer email address space using that endpoint at 15 requests per second from a single IP — under the rate limit on the auth endpoint — and receive confirmation of every valid account. The WAF had no visibility into what the endpoint's response meant. It only counted requests.

Application-layer rate limiting requires context the WAF does not have: user identity, session state, business logic semantics. A WAF can count requests to /api/v1/auth. It cannot count failed authentication attempts per user account across multiple source IPs. Those are different counters measuring different threat surfaces, and the one that matters for credential stuffing is the second one.

IP-based versus token-based versus application-layer rate limiting: what each actually stops

IP-based rate limiting at WAF or load balancer

Effective against single-source high-volume attacks and basic scraping from non-rotating IPs. Fails against distributed attacks using residential proxy pools, fails against attacks distributed across time windows, and has no visibility into which user account or business logic object is being targeted. Configuration is straightforward and requires no application changes.

In practice:

Stops unsophisticated attackers and automated scanners. Does not stop credential stuffing campaigns, organized scraping operations, or any attacker willing to spend under $100/month on proxy infrastructure. Organizations that rely solely on this layer are protected against noise and exposed to targeted attacks.

Token-based rate limiting at API gateway

Limits requests per API key or OAuth token rather than per IP. Effective when each token maps to a single legitimate user or service. Fails when tokens are compromised or when the application issues tokens to unauthenticated users for public endpoints. Requires authentication infrastructure to be solid before rate limiting on top of it provides meaningful protection.

In practice:

Significantly better for authenticated API surfaces. The assumption that one token equals one legitimate actor holds for enterprise API consumers; it breaks for consumer applications where account takeover means a compromised token is an attacker token. Token-based limits need to be paired with anomaly detection on token behavior, not just request volume per token.

Application-layer rate limiting on business logic objects

Counts events that matter to the business: failed authentication attempts per user account, password reset requests per email address, OTP verification attempts per session. Source IP is irrelevant to this counter. Effective against distributed credential stuffing because the attack concentrates on account objects regardless of how many source IPs it uses. Requires implementation in application code or in a dedicated fraud/abuse detection layer.

In practice:

The only control that addresses the attack pattern credential stuffing campaigns actually use. Harder to implement than network-layer controls because it requires application changes and needs tuning per endpoint based on legitimate usage patterns. Organizations that implement this layer consistently find that their previous IP-based configuration was stopping a small fraction of the actual attack surface.

What Vulnox assessments find in real API environments

Assessment base: Pattern observations from Vulnox vulnerability assessments of SaaS, fintech, and e-commerce environments, 2023–2024.

WAF rate limiting configured on authentication endpoints, absent on adjacent endpoints that leak equivalent information

In the majority of assessed environments, rate limiting was applied to the most obvious authentication endpoints — login, password reset, MFA verification. Adjacent endpoints that return information an attacker needs to execute a credential stuffing campaign — email existence checks, username availability, account recovery flows — were either unrated or rated at thresholds calibrated for scraping protection rather than account enumeration protection. The distinction between 'authentication endpoint' and 'account enumeration endpoint' is not always obvious to the team configuring the WAF, and WAF rules are typically applied by endpoint path rather than by the semantic value of the response.

Implication:

Clients believed their authentication surface was rate limited because their authentication endpoints were rate limited. The endpoints attackers actually use to build valid account lists before executing credential stuffing were open. The WAF configuration was accurate — those endpoints were not authentication endpoints. The threat model was incomplete.

Internal microservice APIs with no rate limiting and network-layer-only authentication

In environments using microservice architectures, Vulnox consistently found internal service APIs that applied no rate limiting and validated callers only by verifying that the request originated from within the internal network or service mesh. The assumption embedded in that architecture is that nothing malicious can reach the internal network. Once any perimeter control fails — a compromised external service, a server-side request forgery vulnerability, a misconfigured internal load balancer — the internal APIs are fully open to abuse. No rate limiting means no detection signal either: an attacker enumerating internal data through a compromised microservice generates no alerts because there is no counter to exceed.

Implication:

The clients' position was that internal APIs did not need rate limiting because they were internal. The actual risk is that the internal designation is an architectural assumption that collapses under lateral movement. OWASP API4 applies to internal APIs. The blast radius of a single compromised internal service in an environment where every other internal API trusts it unconditionally is the entire internal API surface.

Rate limit thresholds set at deployment and never reviewed

In assessed environments where rate limiting had been deployed for more than 12 months, Vulnox found that thresholds had been set during initial deployment based on traffic volumes at that time and had not been reviewed since. Organizations that had grown significantly — doubled API traffic, added new user segments, expanded geographic reach — were operating with thresholds calibrated to a traffic baseline that no longer reflected their environment. Some had thresholds set so conservatively that they were generating false positives on legitimate high-volume API consumers. Others had traffic patterns that had grown past original thresholds without triggering anything because the threshold had been raised to stop the false positives and was now too permissive to stop low-rate attacks.

Implication:

Rate limiting is not a set-and-forget control. The legitimate traffic baseline it needs to be calibrated against changes continuously. Organizations that review WAF configurations annually are operating with rate limits that were accurate 11 months ago.

What rate limiting programs consistently miss

GraphQL and non-REST API surfaces

Rate limiting implementations designed for REST APIs count HTTP requests per endpoint. GraphQL APIs receive a single endpoint (typically /graphql) and express all operations as request body content. A WAF configured to rate limit by endpoint path applies one limit to all GraphQL operations regardless of complexity or resource consumption. An attacker who sends deeply nested queries or introspection requests designed to enumerate the schema does so through the same endpoint path as a legitimate two-field query. Request count is the wrong metric for GraphQL — query complexity or depth is the relevant constraint, and WAF-layer rate limiting has no access to that information. Vulnox assessments of environments that had migrated from REST to GraphQL found that WAF rate limiting configurations had not been updated to reflect the changed API surface.

Rate limit responses that confirm valid accounts

A 429 response from a login endpoint tells an attacker two things: the rate limit threshold, and — if the 429 is only returned for valid accounts — whether the account exists. Some implementations apply rate limiting per account object: too many failed attempts against account X triggers a 429 for account X. Too many failed attempts against a nonexistent account triggers nothing, because there is no account object to increment a counter against. The difference in response between 429 (real account, rate limited) and 401 (nonexistent account, no rate limit applied) becomes an account enumeration oracle. The rate limiting mechanism itself leaks the information it was partially deployed to protect.

Burst allowances that exceed the attack window

Token bucket and leaky bucket rate limiting algorithms include burst allowances — headroom above the sustained rate limit that allows legitimate traffic spikes without false positives. Those burst allowances are calibrated for legitimate use cases: a user who opens the app after several hours offline and generates a cluster of API calls. Credential stuffing toolkits are aware of burst allowances and exploit them: send the burst-allowed volume, pause to let the bucket refill, send another burst. The sustained rate limit never triggers. The attack proceeds in batches sized to stay within burst headroom. Organizations that set burst allowances based on legitimate traffic patterns without considering how those allowances interact with attack timing have effectively published their attack cadence tolerance.

What clients say before assessment and what the data shows underneath

  • 'Our WAF handles rate limiting. We configured it when we deployed the API gateway and it has been running fine since.'

    Root cause:

    'Running fine' means 'generating no alerts.' No alerts from a rate limiting system can mean attacks are being blocked, or it can mean attacks are staying under thresholds. Organizations with no distributed attack simulation in their testing history cannot distinguish between these two states. The WAF is processing requests correctly. Whether the thresholds it is enforcing correspond to the actual threat surface has never been validated.

  • 'We tested our rate limiting and it works. We hit the endpoint at twice the threshold and got 429s.'

    Root cause:

    Single-source high-volume testing validates the threshold mechanism. It does not validate the threat model. Credential stuffing campaigns do not operate at twice the threshold from a single IP. They operate at a fraction of the threshold from many thousands of IPs simultaneously. A test that confirms the 429 fires at 2x the threshold from one IP has confirmed that the mechanism works and said nothing about whether the configuration stops the attack it was meant to stop.

  • 'We don't need rate limiting on internal APIs — they're not exposed to the internet.'

    Root cause:

    The threat model for internal APIs is lateral movement after perimeter compromise, not direct external attack. The relevant question is not 'can an external attacker reach this API directly' but 'what can an attacker do with this API after compromising any service that can reach it.' In microservice architectures where services authenticate to each other by network location rather than by identity, compromising one service means inheriting its access to every internal API it communicates with, at whatever rate the API allows.

  • 'We have anomaly detection on our API traffic so we would see an attack even if rate limiting missed it.'

    Root cause:

    Anomaly detection on traffic volume detects attacks that look anomalous in volume terms. Credential stuffing campaigns operated through residential proxy pools at sub-threshold per-IP rates produce traffic that looks like normal API usage distributed across many legitimate-looking source addresses. Volume-based anomaly detection sees nothing unusual. The attack is anomalous only when you count failed authentication attempts per target account — a counter that exists in application logs and is absent from network-layer monitoring.

Where API rate limiting failures are heading

  1. By end of 2026, credential stuffing campaigns will routinely use LLM-generated request timing and behavioral patterns to mimic legitimate user sessions, rendering static rate limit thresholds and behavioral anomaly detection based on request cadence ineffective for a meaningful share of targeted attacks against consumer applications.

    Current credential stuffing toolkits use configurable delays and rotation patterns that are static — the same toolkit produces similar timing fingerprints across campaigns. LLM-generated behavioral simulation can produce per-session timing variation that matches the statistical distribution of real user behavior rather than a fixed delay pattern. The raw capability exists today in consumer LLM APIs at low cost. The integration into abuse tooling is the remaining step, and the credential stuffing toolkit market has historically adopted available automation capabilities quickly. Organizations whose rate limiting and anomaly detection rely on request cadence as a distinguishing signal will find that signal degraded.

    Confidence: mediumNo documented credential stuffing campaigns using LLM-generated behavioral patterns in published threat intelligence reports by end of 2026.
  2. Within 18 months, at least one significant data exposure at a mid-market SaaS company will be traced to an internal API with no rate limiting that was reached through a server-side request forgery vulnerability in a public-facing service — a breach pattern that existing WAF and API gateway monitoring would not have detected.

    SSRF is consistently underrated as an internal API access vector because the path from SSRF to internal API abuse requires chaining two findings: the SSRF itself and the knowledge of internal API structure. Automated scanners find SSRF in isolation. The internal APIs they enable access to are invisible to external assessment. As microservice architectures become standard in mid-market SaaS and internal APIs accumulate without rate limiting or strong authentication, the blast radius of a single SSRF vulnerability expands. The combination of widespread SSRF findings and widespread internal API exposure without rate limiting is a structural setup for exactly this breach pattern.

    Confidence: highNo publicly disclosed breach matching this pattern (SSRF to internal API to data exposure, no WAF detection) in mid-market SaaS by October 2027.

Further Reading

Frequently Asked Questions

Why does IP-based rate limiting fail against credential stuffing attacks?

Credential stuffing campaigns distribute requests across thousands of rotating residential IP addresses — commercial proxy pools cost under $50/month for 10,000 rotating IPs. Each individual IP sends a small number of requests, staying below per-IP thresholds. The WAF blocks nothing because no single IP exceeds the limit, while the application processes every authentication attempt in the distributed campaign. IP-based rate limiting stops single-source high-volume attacks. It does not stop distributed low-volume attacks, which is the pattern credential stuffing toolkits actually use.

What is the difference between WAF rate limiting and application-layer rate limiting for APIs?

WAF rate limiting counts HTTP requests per source IP per endpoint path. It has no visibility into what the requests mean to the application. Application-layer rate limiting counts events that matter to business logic: failed authentication attempts per user account, password reset requests per email address, OTP verification attempts per session. Source IP is irrelevant to application-layer counters — a credential stuffing attack distributed across 50,000 IPs still increments the per-account failed attempt counter on every targeted account. WAF rate limiting and application-layer rate limiting address different attack surfaces and are not substitutes for each other.

Do internal microservice APIs need rate limiting if they are not exposed to the internet?

Yes. The threat model for internal APIs is lateral movement after perimeter compromise, not direct external access. In microservice architectures where services authenticate to each other by network location, compromising one service inherits its access to every internal API it communicates with. An internal API with no rate limiting and no strong per-caller authentication is fully open to abuse once any service that can reach it is compromised. Vulnox assessments consistently find internal service APIs with no rate limiting in environments whose public-facing APIs are well-protected — the internal surface is the larger exposure in many microservice architectures.

How should API rate limiting be tested to validate it works against real attack patterns?

Testing rate limiting by hitting an endpoint from a single source at twice the threshold confirms the mechanism fires but says nothing about whether the configuration stops realistic attacks. Effective validation requires simulating the request distribution patterns of actual credential stuffing toolkits: distribute requests across multiple source IPs at sub-threshold per-IP volumes, test burst allowance exploitation by timing requests to stay within burst headroom, and verify that application-layer counters increment correctly for per-account failed attempts regardless of source IP. In Vulnox assessments, none of the clients in a recent cohort had tested rate limiting against distributed request patterns — all had tested single-source high-volume scenarios only.

Can a rate limiting 429 response leak account existence information?

Yes, in implementations where rate limiting is applied per account object. If the application increments a failed-attempt counter against a real account and returns 429 when the counter exceeds a threshold, but returns 401 for every attempt against a nonexistent account because there is no counter to increment, the difference in response code becomes an account enumeration oracle. Attackers who receive 429 know the account exists; those who receive only 401 know it does not. The rate limiting mechanism itself leaks the information it was partially deployed to protect. The fix is to apply the same response behavior regardless of account existence.

Why does GraphQL break standard WAF rate limiting configurations?

WAF rate limiting for REST APIs counts requests per endpoint path. GraphQL APIs expose a single endpoint and express all operations in the request body. A WAF configured by path applies one rate limit to all GraphQL operations regardless of their complexity or resource consumption. A deeply nested query designed to enumerate schema or exhaust server resources passes through the same rate limit as a lightweight two-field query. Request count is the wrong metric for GraphQL — query complexity or depth is the relevant constraint, and WAF-layer rate limiting has no access to request body semantics. Environments that migrated from REST to GraphQL without updating their rate limiting approach retained configurations that were accurate for the old architecture and ineffective for the new one.

How often should API rate limit thresholds be reviewed and updated?

Rate limit thresholds need to be recalibrated whenever the legitimate traffic baseline changes significantly — after major product launches, user growth milestones, new geographic markets, or new API consumer segments. Static thresholds set at deployment become miscalibrated as traffic patterns evolve: organizations that have grown substantially since deployment may be generating false positives on legitimate high-volume consumers, prompting threshold increases that inadvertently widen the attack window. Vulnox assessments consistently find thresholds that were accurate at deployment and had not been reviewed in over a year, by which point the traffic environment they were calibrated against no longer existed.

Related Articles

API security assessment: what automated tools miss and manual testing finds

API security assessment: what automated tools miss and manual testing finds

Automated API security tools find the vulnerabilities they were designed to look for. The findings that matter in real assessments, broken object-level authorization, JWT algorithm confusion, and unauthenticated internal endpoints, require a tester who understands what the API is supposed to do before probing what it actually does.

CVSS score explained: what the metric captures, what it misses, and how to fix your prioritization

CVSS score explained: what the metric captures, what it misses, and how to fix your prioritization

In 40% of Vulnox assessments, vulnerabilities scored CVSS 9.0 or higher were on systems with compensating controls that materially reduced the actual risk. The score was accurate. The priority order it implied was not. This guide covers how to use CVSS correctly and what to layer on top of it.

Post-breach vulnerability assessment: what the attacker left behind

Post-breach vulnerability assessment: what the attacker left behind

Most post-breach assessments start too late and end too early. They confirm what was hit, not what the attacker mapped before they moved. The second breach usually comes from the reconnaissance that happened in the first.

Ready to Secure Your Digital Assets?

Get a comprehensive vulnerability assessment for your website today.