What is Lack of Resources & Rate Limiting? Ways to Exploit, Examples and Impact
Deep dive into Rate Limiting and Resource Exhaustion. Learn technical exploitation, bypass techniques, and how to secure your APIs against automated attacks.
In the modern landscape of interconnected web applications and microservices, APIs have become the backbone of digital communication. However, this accessibility often comes at a price: the risk of resource exhaustion. When an application fails to impose limits on how many times a user can access a resource or how much of that resource they can consume, it falls victim to a vulnerability known as "Lack of Resources and Rate Limiting."
This vulnerability, frequently categorized under the OWASP API Security Top 10 (specifically API4:2019 and evolving into Unrestricted Resource Consumption in API4:2023), allows attackers to overwhelm servers, inflate operational costs, and bypass security controls. In this guide, we will dive deep into the technical mechanics of rate limiting, explore how attackers exploit these weaknesses, and provide actionable remediation strategies.
What is Lack of Resources and Rate Limiting?
To understand this vulnerability, we must distinguish between its two primary components: resource consumption and request frequency.
Lack of Resources
This refers to a scenario where an application does not limit the amount of system resources (CPU, memory, disk space, or network bandwidth) a single request or user can consume. For example, if a user can request an API to generate a massive PDF report with millions of rows without any constraints, the server might run out of memory, leading to a Denial of Service (DoS) for all other users.
Lack of Rate Limiting
Rate limiting is the process of controlling the number of requests a client can make to a server within a specific timeframe. Without rate limiting, an attacker can send thousands of requests per second. This is often used to facilitate brute-force attacks against login forms, scrape sensitive data, or perform "bombing" attacks (SMS/Email) that incur financial costs for the service provider.
Common Rate Limiting Algorithms
Before we look at exploits, it is helpful to understand how developers typically implement these protections. Most modern web servers and API gateways use one of the following algorithms:
- Fixed Window Counter: The simplest method. It tracks the number of requests in a fixed timeframe (e.g., 60 seconds). If the limit is 100, the 101st request is blocked until the next minute starts. The flaw here is that a burst of 200 requests can happen at the edge of two windows (100 at 0:59 and 100 at 1:01).
- Sliding Window Log: This tracks the timestamp of every request. While highly accurate, it is memory-intensive because it stores every request's timestamp.
- Token Bucket: Users are given a "bucket" that fills with tokens at a fixed rate. Each request consumes a token. If the bucket is empty, the request is dropped. This allows for small bursts of traffic while maintaining a long-term average rate.
- Leaky Bucket: Requests enter a bucket and are processed at a constant, steady rate. If the bucket overflows, new requests are discarded. This is excellent for smoothing out traffic spikes.
How Attackers Exploit a Lack of Rate Limiting
When these protections are missing or poorly configured, attackers use several techniques to disrupt services or gain unauthorized access.
1. Brute-Forcing and Credential Stuffing
Without a limit on login attempts, an attacker can use a tool like Hydra or Burp Suite Intruder to test thousands of password combinations against a single username.
Example Payload (HTTP Request):
POST /api/v1/login HTTP/1.1
Host: target-app.com
Content-Type: application/json
{
"username": "admin",
"password": "password123"
}
An attacker might automate this in Python:
import requests
url = "https://target-app.com/api/v1/login"
passwords = ["123456", "password", "admin123", "qwerty"]
for pwd in passwords:
response = requests.post(url, json={"username": "admin", "password": pwd})
if "Success" in response.text:
print(f"Found password: {pwd}")
break
Without rate limiting, the server will process all these requests, eventually allowing the attacker to guess the correct credentials.
2. Unrestricted Resource Consumption (DoS)
This occurs when an endpoint performs an "expensive" operation. If an attacker identifies an endpoint that triggers heavy database queries or file processing, they can flood it to crash the server.
Technical Scenario:
Imagine an endpoint /api/search?query=term&limit=10. If the limit parameter is not validated, an attacker could change it to limit=1000000. The database might attempt to fetch a million records, spiking CPU and memory usage to 100%.
3. SMS and Email Bombing
Many applications offer "Forgot Password" or "OTP Verification" features. If these endpoints aren't rate-limited, an attacker can trigger thousands of SMS messages to a single phone number. Not only is this harassment for the user, but it also drains the company's API credits with providers like Twilio or AWS SNS.
Bypassing Rate Limits: Technical Techniques
Security professionals must be aware that even when rate limiting is present, it can often be bypassed if the implementation is flawed. Here are common bypass methods:
1. Header Manipulation
Many rate limiters identify users by their IP address. Attackers can spoof their IP by using headers that are commonly added by load balancers or proxies.
Headers to test:
X-Forwarded-For: 127.0.0.1X-Originating-IP: 1.2.3.4X-Remote-IP: 5.6.7.8X-Client-IP: 9.10.11.12
By rotating the IP address in these headers for every request, an attacker can trick the rate limiter into thinking each request is coming from a different user.
2. Changing Request Formats
Sometimes, a rate limiter is only applied to application/json requests. By changing the Content-Type to application/xml or application/x-www-form-urlencoded, an attacker might bypass the filter entirely if the backend supports multiple formats but the security layer does not.
3. Appending Null Bytes or Random Parameters
If a rate limiter keys its cache on the exact URL string, adding a random query parameter might bypass it:
- Request 1:
/api/data?id=1&nonce=1 - Request 2:
/api/data?id=1&nonce=2
The Impact of Exploitation
The consequences of failing to implement resource limits are far-reaching:
- Financial Loss: High bills from third-party API providers (SMS/Email) and increased cloud infrastructure costs due to auto-scaling during a DoS attack.
- Service Unavailability: Legitimate users are unable to access the application because the server is busy processing the attacker's requests.
- Data Theft: Attackers can scrape entire databases by making millions of small requests that fly under the radar of traditional monitoring.
- Account Takeover: Successful brute-force attacks lead to compromised user accounts and potential data breaches.
How to Prevent and Mitigate
To protect your infrastructure, a multi-layered approach is required:
- Implement Global and Per-Endpoint Limits: Use an API Gateway (like Kong, Apigee, or AWS API Gateway) to enforce limits. Critical endpoints like
/login,/register, and/forgot-passwordshould have much stricter limits than public data endpoints. - Validate Input Sizes: Never allow users to define the size of a resource request (like a database
limitoroffset) without a hard-coded maximum value. - Use CAPTCHAs: For sensitive actions, introduce a CAPTCHA after a certain number of failed attempts to ensure the user is human.
- Monitor Resource Usage: Implement alerts for spikes in CPU, memory, and outgoing network traffic. Sudden increases often indicate an ongoing resource exhaustion attack.
- Identify Users Correctly: Do not rely solely on the IP address. Use session tokens, API keys, or JWT claims to track and limit requests per user.
Conclusion
Lack of resources and rate limiting is a silent killer for web applications. While it may not seem as flashy as a SQL Injection, its ability to take down entire platforms and facilitate large-scale automated attacks makes it a top-tier security concern. By understanding the algorithms and bypass techniques used by attackers, developers can build more resilient systems that withstand the pressures of the modern web.
To proactively monitor your organization's external attack surface and catch exposures before attackers do, try Jsmon. Jsmon helps you identify sensitive endpoints and infrastructure changes that might be missing critical rate-limiting protections.