Sleep Injection

ID

python.sleep_injection

Severity

critical

Resource

Injection

Language

Python

Tags

CWE:400, NIST.SP.800-53, OWASP:2021:A3, PCI-DSS:6.5.1, PCI-DSS:6.5.6

Description

Improper neutralization of external input used to make a thread to wait.

Rationale

Sleep injection vulnerabilities occur when user-controlled inputs influence the duration of sleep statements, leading to potential exploitation by attackers to cause performance issues.

These vulnerabilities, categorized under CWE-400, can be caused by improper handling of user input without sufficient validation or sanitization, allowing malicious parties to submit large delays that can hinder application availability and responsiveness.

Consider the following vulnerable Python code:

import time
from flask import request, Flask

app = Flask(__name__)

@app.route('/delay')
def delay():
    seconds = int(request.args.get('sleep_time', 1))
    time.sleep(seconds)
    return "Slept for {} seconds".format(seconds)

Here, the sleep duration is controlled by the sleep_time parameter. A malicious user could pass a large number like sleep_time=10000 to delay the server response excessively or tie up server threads.

This kind of issue can be critical in environments where thread or request handling resources are limited (e.g., WSGI servers like Gunicorn or uWSGI).

Remediation

To mitigate sleep injection issues in Java, you should ensure proper validation and sanitization of all user inputs that control sleep durations. Employing input validation to enforce sane limits on sleep duration can prevent misuse.

A safe refactoring of the previous example might look like this:

import time
from flask import request, Flask, abort

app = Flask(__name__)

@app.route('/delay')
def delay():
    try:
        seconds = int(request.args.get('sleep_time', 1))
    except ValueError:
        abort(400, "Invalid input")

    # Clamp the sleep time to a safe, acceptable range
    if seconds < 0 or seconds > 5:
        abort(400, "Sleep duration out of allowed bounds")

    time.sleep(seconds)
    return "Slept for {} seconds".format(seconds)

In this corrected version: - Inputs are parsed safely. - An upper bound of 5 seconds is enforced to prevent abuse. - Negative and malformed inputs are rejected with appropriate HTTP responses.

As a best practice, avoid using sleep-based delays for any kind of logic that depends on user input unless it’s strictly bounded and controlled.

Configuration

The detector has the following configurable parameters:

  • sources, that indicates the source kinds to check.

  • neutralizations, that indicates the neutralization kinds to check.

Unless you need to change the default behavior, you typically do not need to configure this detector.

References