Weakness reference
CWE-770

Allocation of Resources Without Limits or Throttling

This weakness occurs when an application allocates resources—such as memory, disk space, network connections, or processing time—without enforcing any upper…

01Summary

This weakness occurs when an application allocates resources—such as memory, disk space, network connections, or processing time—without enforcing any upper limits or throttling mechanisms. An attacker can exploit this by requesting excessive resources, causing the application to exhaust available capacity and become unavailable to legitimate users.

02How It Happens

Applications often need to allocate resources dynamically in response to user requests: uploading files, creating database connections, processing data, or storing temporary files. When no safeguards are in place, an attacker can submit many requests or request unusually large amounts of resources. The application dutifully allocates each one without checking whether total consumption exceeds safe thresholds. Over time, memory fills up, disk space runs out, connection pools are exhausted, or CPU usage spikes uncontrollably. The application slows to a crawl or crashes, denying service to everyone.

03Real-World Impact

Resource exhaustion attacks can render a website or service completely unavailable. A file upload feature without size limits can fill a server's disk. An API endpoint that creates in-memory objects without bounds can cause out-of-memory crashes. Unthrottled connection handling can exhaust database connection pools, locking out all users. These attacks are often easier to execute than traditional exploits and require no special privileges—just repeated requests or large payloads.

04Vulnerable & Fixed Patterns

Vulnerable pattern
import tempfile
import os

def handle_file_upload(uploaded_file):
    # No size limit, no throttling
    temp_dir = tempfile.gettempdir()
    file_path = os.path.join(temp_dir, uploaded_file.filename)
    
    with open(file_path, 'wb') as f:
        f.write(uploaded_file.read())  # Reads entire file into memory
    
    return f"File saved to {file_path}"

Why it's vulnerable:
The code reads the entire uploaded file into memory without checking its size. An attacker can upload gigabyte-sized files repeatedly, exhausting available RAM and disk space.

Fixed pattern
import tempfile
import os

MAX_FILE_SIZE = 10 * 1024 * 1024  # 10 MB
CHUNK_SIZE = 8192

def handle_file_upload(uploaded_file):
    temp_dir = tempfile.gettempdir()
    file_path = os.path.join(temp_dir, uploaded_file.filename)
    
    bytes_written = 0
    with open(file_path, 'wb') as f:
        while True:
            chunk = uploaded_file.read(CHUNK_SIZE)
            if not chunk:
                break
            bytes_written += len(chunk)
            if bytes_written > MAX_FILE_SIZE:
                os.remove(file_path)
                raise ValueError("File exceeds maximum size")
            f.write(chunk)
    
    return f"File saved to {file_path}"
Vulnerable pattern
<?php
// No limit on uploaded file size or number of concurrent uploads
$upload_dir = '/tmp/uploads/';

if ($_FILES['userfile']['error'] == UPLOAD_ERR_OK) {
    $tmp_name = $_FILES['userfile']['tmp_name'];
    $name = $_FILES['userfile']['name'];
    move_uploaded_file($tmp_name, $upload_dir . $name);
    echo "Upload successful";
}
?>

Why it's vulnerable:
PHP's default upload_max_filesize and post_max_size may be large, and there is no per-request or per-user throttling. An attacker can upload many large files or trigger many simultaneous uploads, filling disk space.

Fixed pattern
<?php
define('MAX_FILE_SIZE', 5 * 1024 * 1024);  // 5 MB
define('MAX_UPLOADS_PER_HOUR', 10);
$upload_dir = '/tmp/uploads/';

// Check file size before processing
if ($_FILES['userfile']['size'] > MAX_FILE_SIZE) {
    die('File exceeds maximum size');
}

// Check upload rate (simplified; use a database or cache in production)
$user_id = get_current_user_id();
$upload_count = get_user_uploads_this_hour($user_id);
if ($upload_count >= MAX_UPLOADS_PER_HOUR) {
    die('Upload limit exceeded');
}

if ($_FILES['userfile']['error'] == UPLOAD_ERR_OK) {
    $tmp_name = $_FILES['userfile']['tmp_name'];
    $name = sanitize_filename($_FILES['userfile']['name']);
    move_uploaded_file($tmp_name, $upload_dir . $name);
    log_user_upload($user_id);
    echo "Upload successful";
}
?>

05Prevention Checklist

Set explicit maximum limits on file upload sizes, request body sizes, and number of concurrent connections.
Implement rate limiting per user, IP address, or API key to restrict the frequency of resource-intensive operations.
Monitor resource consumption (memory, disk, CPU, open connections) in real time and alert when thresholds are approached.
Use timeouts on long-running operations and enforce maximum execution times for requests.
Configure web server and application framework limits (e.g., max_connections, request_timeout, memory_limit) appropriately for your environment.
Test your application under load to identify resource bottlenecks before they become production issues.

06Signs You May Already Be Affected

Watch for sudden spikes in disk usage, memory consumption, or CPU load without corresponding increases in legitimate traffic. Check application logs for repeated requests from a single IP or user account, or for errors related to resource exhaustion (out-of-memory, disk full, connection pool exhausted). Unexpected slowness or service unavailability during normal traffic levels may also indicate an ongoing resource exhaustion attack.

07Related Recent Vulnerabilities