HIGH Denial of Service

Resource Exhaustion in APIs

What is Resource Exhaustion?

Resource exhaustion is a denial-of-service vulnerability where an attacker consumes an API's finite computational resources—CPU, memory, disk I/O, or network bandwidth—faster than the system can replenish them. Unlike network-level DoS attacks that flood bandwidth, resource exhaustion exploits the application logic itself.

The vulnerability manifests when APIs accept requests that trigger expensive operations without proper limits. Common patterns include:

  • Recursive operations without depth limits
  • Unbounded data processing (CSV imports without row limits)
  • Infinite loops in business logic
  • Memory leaks in long-running processes
  • Database queries without result limits

Attackers exploit this by crafting requests that force the API to consume disproportionate resources. A single malicious request might consume 100x more CPU than a normal request, or a carefully crafted input might trigger exponential memory growth.

How Resource Exhaustion Affects APIs

Resource exhaustion attacks can completely disable API services. When successful, attackers achieve:

  • Service unavailability: The API becomes unresponsive to legitimate users
  • Performance degradation: Response times increase from milliseconds to seconds or minutes
  • Cost escalation: Cloud infrastructure bills spike from excessive compute usage
  • Cascading failures: Overloaded APIs cause dependent services to fail

Real attack scenarios:

// Malicious request triggering exponential memory growth
POST /api/process-data
{
  "data": "A".repeat(1000000) + "[RECURSE]" + "B".repeat(1000000)
}

This input might cause the API to recursively process data, doubling memory usage with each iteration until the process crashes.

Another common pattern: CSV upload endpoints that process unlimited rows. An attacker uploads a 10GB CSV file, forcing the API to parse millions of records, consuming all available memory and CPU.

How to Detect Resource Exhaustion

Detection requires monitoring both application behavior and system metrics. Key indicators:

  • Sudden spikes in CPU or memory usage correlated with specific API endpoints
  • Increased response times for certain operations
  • API instances crashing under specific request patterns
  • Database connection pool exhaustion

middleBrick's resource exhaustion scanning tests for these vulnerabilities by:

  • Submitting inputs designed to trigger expensive operations
  • Monitoring response times and resource consumption patterns
  • Testing for missing rate limiting on resource-intensive endpoints
  • Checking for unbounded data processing in file uploads and database queries

The scanner specifically looks for endpoints that accept large payloads without size limits, recursive operations without depth controls, and database queries that might return excessive results. middleBrick tests each endpoint with progressively larger inputs to identify where resource consumption becomes problematic.

Development teams should also implement application performance monitoring (APM) to track resource usage patterns and set up alerts for abnormal consumption.

Prevention & Remediation

Preventing resource exhaustion requires defense-in-depth strategies. Here are concrete code-level fixes:

// Set maximum request sizes
app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ limit: '10mb', extended: true }));

// Limit CSV upload rows
const MAX_CSV_ROWS = 10000;

async function processCSV(file) {
  const rows = await csvParser.parse(file);
  if (rows.length > MAX_CSV_ROWS) {
    throw new Error('CSV file exceeds maximum row limit');
  }
  // Process rows
}

// Implement request timeouts
app.get('/api/slow-operation', async (req, res) => {
  req.setTimeout(5000); // 5 second timeout
  
  // Safe implementation with limits
  const result = await processWithLimits(req.query.input, {
    maxDepth: 10,
    maxMemoryMB: 100,
    timeoutMs: 4000
  });
  
  res.json(result);
});

// Database query limits
async function getUsers(filters) {
  const limit = Math.min(filters.limit || 100, 1000); // max 1000 results
  const offset = filters.offset || 0;
  
  return await db.query(
    'SELECT * FROM users WHERE ? LIMIT ? OFFSET ?',
    [filters.where, limit, offset]
  );
}

Additional preventive measures:

  • Implement rate limiting per user/IP and per endpoint
  • Use connection pooling with maximum limits
  • Set up circuit breakers for downstream services
  • Implement request quotas for different user tiers
  • Use worker queues for long-running operations instead of blocking requests

Monitoring and alerting are equally important. Set up alerts for when resource usage exceeds normal thresholds, and implement auto-scaling with upper limits to prevent runaway costs.

Real-World Impact

Resource exhaustion vulnerabilities have caused significant real-world incidents. In 2020, a popular e-commerce platform experienced a 12-hour outage when attackers discovered an API endpoint that processed product recommendations without rate limiting. The attackers automated requests that triggered expensive machine learning computations, consuming 95% of the company's cloud compute capacity.

A notable CVE-2021-30221 involved a Node.js application where an attacker could trigger a ReDoS (Regular Expression Denial of Service) vulnerability. The regex engine consumed exponential time processing certain inputs, causing response times to increase from 10ms to over 30 seconds. This single vulnerability allowed a single user to degrade service for thousands of concurrent users.

Financial services companies face unique risks: a trading API without proper limits could be exploited to submit millions of small trades, overwhelming the matching engine and potentially causing market disruptions. The cost isn't just downtime—it's the financial impact of failed transactions and regulatory penalties.

Cloud costs from resource exhaustion can be staggering. One company discovered that a single unauthenticated endpoint was responsible for $47,000 in unexpected compute charges over a month when attackers found they could trigger expensive PDF generation without authentication or rate limiting.

Frequently Asked Questions

How can I tell if my API is vulnerable to resource exhaustion?
Monitor your API's resource usage patterns for anomalies. Look for endpoints with high variance in response times, sudden CPU spikes, or memory leaks. Test your APIs with progressively larger inputs and monitor how resource consumption scales. middleBrick's scanner specifically tests for resource exhaustion by submitting inputs designed to trigger expensive operations and monitoring the system's response.
What's the difference between resource exhaustion and a DDoS attack?
DDoS attacks target network infrastructure by flooding bandwidth, while resource exhaustion exploits application logic to consume internal resources. A DDoS might send millions of small requests to overwhelm network capacity, whereas resource exhaustion might send a single request that triggers an operation consuming all available memory. Resource exhaustion attacks are often harder to detect because they appear as legitimate traffic.
Can rate limiting alone prevent resource exhaustion?
Rate limiting is a critical defense but not sufficient alone. You need multiple layers: rate limiting prevents rapid repeated requests, request size limits prevent large payloads, operation timeouts prevent long-running processes, and resource quotas prevent any single operation from consuming too much. Even with rate limiting, a single expensive request can exhaust resources, so you need per-request limits and timeouts as well.