Cloudanix VulnDB

CVE-2024-49767

None

CVSS

—

EPSS

1.1%

Published

Oct 25, 2024

CISA due date

—

Cloudanix analysis

Next patch cycle SSVC: Track

Some web apps that accept file uploads can be forced offline by specially made uploads unless their underlying Python web library is updated.

Exploitation
Remote Unauthenticated
Attacker needs
None
Complexity
Low
Impact
Denial Of Service
Component
Library
Class
Denial of service
Remediation
Upgrade
Effort
Medium
Patch risk
Low

What it actually does

Werkzeug versions prior to 3.0.6 can consume disproportionate memory while parsing specially crafted multipart/form-data requests through werkzeug.formparser.MultiPartParser, which is commonly used by Flask applications for form and file upload handling. The vulnerable parser may allocate and block roughly 3 to 8 times the submitted upload size in main memory, with no effective upper bound enforced by the vulnerable code path. A sufficiently large or sustained upload can exhaust application worker memory, trigger out-of-memory termination, crash the process or container, and make the application unavailable. The issue is a denial-of-service flaw; it does not directly enable code execution, data theft, or authentication bypass.

Why it matters to the business

Public-facing Flask or Werkzeug-based applications that accept file uploads or multipart form submissions can be taken offline by relatively simple HTTP requests, potentially causing service outages, failed transactions, degraded customer experience, autoscaling cost spikes, and incident response overhead. Although the EPSS score is currently low, it is a straightforward resource exhaustion condition in a widely used Python web stack, so internet-exposed upload endpoints should be treated as operationally important even though it is not listed in CISA KEV and there is no known ransomware association.

How an attack unfolds

An attacker first identifies an application endpoint that accepts multipart/form-data, such as a file upload, form submission, API attachment, or any Flask route that reads uploaded form data. The attacker then sends a crafted multipart request designed to trigger inefficient buffering behavior in Werkzeug's multipart parser. Because vulnerable versions can allocate multiple times the request body size in RAM, the attacker does not need to send traffic equal to the target system's full memory capacity; a high-bandwidth single upload or several concurrent uploads can rapidly consume available memory. As memory pressure rises, application workers may block, be killed by the operating system or container runtime, return 500/502/503/504 errors, or cause the hosting platform to restart instances. Repeating the request can keep the service unstable until the vulnerable parser is upgraded or effective request size, rate, and memory limits are enforced.

How to fix it

Upgrade Werkzeug to version 3.0.6 or later wherever Werkzeug is used directly or transitively through Flask or another Python web framework. If consuming Werkzeug from source, use a version that includes commit 5eaefc3996aa5cc8c5237d8b82f1b89eed6ea624 or a later fixed revision. Rebuild and redeploy applications after dependency updates, including container images and serverless packages, because Python dependency pinning may leave vulnerable versions in runtime artifacts. As defense in depth, enforce maximum request body sizes at the edge proxy, load balancer, application server, and framework level; restrict upload size and file count; apply authentication or authorization to upload endpoints where practical; configure worker memory limits and restart policies; and use rate limiting or concurrency limits for multipart upload routes. For Flask deployments, review MAX_CONTENT_LENGTH and any reverse proxy limits such as client_max_body_size, LimitRequestBody, or equivalent controls, but do not rely on limits alone as a substitute for upgrading.

How to confirm the fix worked

Confirm exposure by inventorying Python dependencies and verifying that installed Werkzeug versions are 3.0.6 or later. Use package metadata and lockfiles such as pip freeze, pip show Werkzeug, requirements.txt, poetry.lock, Pipfile.lock, uv.lock, or SBOM results to identify vulnerable versions below 3.0.6. Validate deployed artifacts, not only source repositories, by inspecting container images, virtual environments, build outputs, and runtime dependency reports. Confirm that upload endpoints have explicit request size limits at both the application and ingress layers. After patching, run controlled multipart upload tests in a non-production environment to verify that oversized or malformed multipart requests are rejected or bounded without excessive memory growth. Monitor production after deployment for reduced out-of-memory events, worker restarts, and error-rate spikes on multipart endpoints.

Typical attack path

  1. Discover a Flask or Werkzeug-based web application with endpoints that accept multipart/form-data requests.
  2. Select upload or form-submission routes that cause the application to parse request.files or request.form.
  3. Send a specially crafted multipart/form-data POST request with a large body or sustained upload stream.
  4. Cause the vulnerable Werkzeug MultiPartParser to allocate several times the upload size in application memory.
  5. Repeat or parallelize requests to exhaust worker, container, or host memory.
  6. Trigger application crashes, out-of-memory kills, worker restarts, elevated latency, and service unavailability.

How to detect it

To determine whether this was already exploited, correlate HTTP access logs, web application firewall logs, reverse proxy logs, application logs, container/runtime events, and host system logs. Look for unusually large or long-running POST requests with Content-Type multipart/form-data, especially to upload or form endpoints, followed by sudden increases in memory usage, worker timeouts, HTTP 500/502/503/504 responses, process restarts, container OOMKilled events, or Linux OOM killer messages. Useful log sources include NGINX or Apache access/error logs, API gateway logs, WAF events, Gunicorn/uWSGI/Waitress logs, Flask application logs, Kubernetes pod events, container runtime logs, systemd journal, kernel logs, and cloud load balancer metrics. Investigate repeated multipart uploads from the same source, many concurrent multipart uploads from distributed sources, anomalously large request bodies, requests that terminate before completion, and request timing that aligns with memory exhaustion or service restarts. Because exploitation does not require a unique payload string and may resemble legitimate uploads, detection should focus on behavioral correlation: multipart request volume and size, endpoint targeting, memory pressure, and crash or restart artifacts.

  • Content-Type: multipart/form-data
  • werkzeug.formparser.MultiPartParser
  • MemoryError
  • Out of memory
  • oom-killer
  • Killed process
  • OOMKilled
  • signal 9
  • Worker timeout
  • WORKER TIMEOUT
  • worker timeout
  • upstream prematurely closed connection
  • upstream timed out
  • client intended to send too large body
  • Request Entity Too Large
  • 413 Request Entity Too Large
  • 502 Bad Gateway
  • 503 Service Unavailable
  • 504 Gateway Timeout
  • POST

What your security team should do

  • Prioritize upgrading all Werkzeug deployments below 3.0.6, especially internet-facing Flask applications and services that accept file uploads or multipart form submissions.
  • Search dependency manifests, container images, and SBOMs for Werkzeug versions earlier than 3.0.6 and track remediation through redeployment, not just code changes.
  • Apply or verify request body size limits at reverse proxies, API gateways, WSGI servers, and application framework settings for all multipart upload routes.
  • Add rate limits and concurrency controls for unauthenticated or high-risk upload endpoints to reduce the feasibility of memory-exhaustion attempts.
  • Review monitoring for memory utilization, out-of-memory kills, worker restarts, and HTTP 5xx spikes correlated with multipart/form-data POST requests since the publication date.
  • Create SIEM detections for large or repeated multipart/form-data requests followed by process restarts, OOM killer messages, or elevated 502/503/504 responses.
  • Ensure incident response runbooks include rapid mitigations such as temporarily lowering upload size limits, disabling nonessential upload endpoints, or blocking abusive sources at the edge.

The record

Werkzeug is a Web Server Gateway Interface web application library. Applications using `werkzeug.formparser.MultiPartParser` corresponding to a version of Werkzeug prior to 3.0.6 to parse `multipart/form-data` requests (e.g. all flask applications) are vulnerable to a relatively simple but effective resource exhaustion (denial of service) attack. A specifically crafted form submission request can cause the parser to allocate and block 3 to 8 times the upload size in main memory. There is no upper limit; a single upload at 1 Gbit/s can exhaust 32 GB of RAM in less than 60 seconds. Werkzeug version 3.0.6 fixes this issue.

Affected packages

Ecosystem Package Introduced Fixed
PyPI quart 0 0.19.7
PyPI quart 0 0.20.0
PyPI werkzeug 0 3.0.6
Chainguard airflow-2 0 2.11.1-r0
Chainguard airflow-2-compat 0 2.11.0-r15
Chainguard airflow-2-iamguarded-compat 0 2.11.0-r15
Chainguard airflow-3 0 3.0.1-r1
Chainguard airflow-3-bitnami-compat 0 3.0.1-r1
Chainguard airflow-3-compat 0 3.0.1-r1
Chainguard airflow-3-compat 0 3.1.2-r0
Chainguard airflow-3-iamguarded-compat 0 3.1.2-r0
Chainguard airflow-core-2 0 2.11.1-r0
Chainguard airflow-core-2-compat 0 2.11.0-r8
Chainguard airflow-core-2-oci-entrypoint 0 2.11.0-r8
Chainguard emissary 0 3.9.1-r4
Chainguard emissary-apiext 0 3.9.1-r4
Chainguard emissary-oci-entrypoint 0 3.9.1-r4
Chainguard kubeflow-jupyter-web-app 0 1.9.2-r1
Chainguard kubeflow-pipelines-visualization-server 0 2.4.0-r0
Chainguard kubeflow-volumes-web-app 0 1.9.2-r1
Chainguard mlflow 0 2.21.0-r0
Chainguard mlflow-bitnami 0 2.21.0-r0
Chainguard mlflow-iamguarded-compat 0 2.21.0-r0
Chainguard py3-supported-werkzeug 0 3.0.6-r0
Chainguard py3-werkzeug 0 3.0.6-r0
Chainguard py3.10-ambassador 0 3.9.1-r4
Chainguard py3.10-werkzeug 0 3.0.6-r0
Chainguard py3.11-ambassador 0 3.9.1-r4
Chainguard py3.11-werkzeug 0 3.0.6-r0
Chainguard py3.12-ambassador 0 3.9.1-r4
Chainguard py3.12-werkzeug 0 3.0.6-r0
Chainguard py3.13-ambassador 0 3.9.1-r4
Chainguard py3.13-werkzeug 0 3.0.6-r0
Chainguard superset 0 4.0.2-r6
Chainguard superset-ci 0 4.0.2-r6
Chainguard superset-entrypoint 0 4.0.2-r6
Chainguard superset-iamguarded-compat 0 4.0.2-r6
Debian:11 python-werkzeug 0 No fix
Debian:11 quart 0 No fix
Debian:12 python-werkzeug 0 No fix
Debian:12 quart 0 No fix
Debian:13 python-werkzeug 0 No fix
Debian:13 python-werkzeug 0 3.1.3-2
Debian:13 quart 0 No fix
Debian:14 python-werkzeug 0 3.1.3-2
Debian:14 quart 0 0.19.9-1
Mageia:9 python-werkzeug 0 3.0.6-1.mga9
SUSE:Linux Enterprise Module for Python 3 15 SP5 python-Werkzeug 0 2.3.6-150400.6.12.1
SUSE:Linux Enterprise Module for Python 3 15 SP6 python-Werkzeug 0 2.3.6-150400.6.12.1
Ubuntu:20.04:LTS python-werkzeug 0 0.16.1+dfsg1-2ubuntu0.2
Ubuntu:22.04:LTS python-werkzeug 0 2.0.2+dfsg1-1ubuntu0.22.04.3
Ubuntu:22.04:LTS quart 0 No fix
Ubuntu:24.04:LTS python-werkzeug 0 3.0.1-3ubuntu0.2
Ubuntu:24.04:LTS quart 0 No fix
Ubuntu:24.10 python-werkzeug 0 3.0.3-1ubuntu0.1
Ubuntu:24.10 quart 0 No fix
Ubuntu:25.04 python-werkzeug 0 3.0.4-1ubuntu1
Ubuntu:25.04 quart 0 No fix
Ubuntu:25.10 quart 0 No fix
Wolfi airflow-3 0 3.0.1-r1
Wolfi airflow-3-bitnami-compat 0 3.0.1-r1
Wolfi airflow-3-compat 0 3.0.1-r1
Wolfi airflow-3-compat 0 3.1.2-r0
Wolfi airflow-3-iamguarded-compat 0 3.1.2-r0
Wolfi emissary 0 3.9.1-r4
Wolfi emissary-apiext 0 3.9.1-r4
Wolfi emissary-oci-entrypoint 0 3.9.1-r4
Wolfi kubeflow-jupyter-web-app 0 1.9.2-r1
Wolfi kubeflow-pipelines-visualization-server 0 2.4.0-r0
Wolfi kubeflow-volumes-web-app 0 1.9.2-r1
Wolfi mlflow 0 2.21.0-r0
Wolfi mlflow-bitnami 0 2.21.0-r0
Wolfi mlflow-iamguarded-compat 0 2.21.0-r0
Wolfi py3-supported-werkzeug 0 3.0.6-r0
Wolfi py3-werkzeug 0 3.0.6-r0
Wolfi py3.10-ambassador 0 3.9.1-r4
Wolfi py3.10-werkzeug 0 3.0.6-r0
Wolfi py3.11-ambassador 0 3.9.1-r4
Wolfi py3.11-werkzeug 0 3.0.6-r0
Wolfi py3.12-ambassador 0 3.9.1-r4
Wolfi py3.12-werkzeug 0 3.0.6-r0
Wolfi py3.13-ambassador 0 3.9.1-r4
Wolfi py3.13-werkzeug 0 3.0.6-r0
Wolfi superset 0 4.0.2-r6
Wolfi superset-ci 0 4.0.2-r6
Wolfi superset-entrypoint 0 4.0.2-r6
Wolfi superset-iamguarded-compat 0 4.0.2-r6
openSUSE:Leap 15.5 python-Werkzeug 0 2.3.6-150400.6.12.1
openSUSE:Leap 15.6 python-Werkzeug 0 2.3.6-150400.6.12.1
openSUSE:Tumbleweed python-Werkzeug 0 3.0.6-1.1

Related vulnerabilities