CVE-2023-46136
High · 8.0CVSS
8.0
EPSS
1.1%
Published
Oct 25, 2023
CISA due date
—
Cloudanix analysis
A flaw in a common web development tool allows an attacker to make a web application crash simply by sending a specially crafted file upload.
- Exploitation
- Adjacent Network
- Attacker needs
- Low Privilege
- Complexity
- Low
- Impact
- Denial Of Service
- Component
- Library
- Class
- Memory Corruption
- Remediation
- Upgrade
- Effort
- Medium
- Patch risk
- Low
What it actually does
The vulnerability exists in the multipart form data parser of the Werkzeug library. When processing a file upload that begins with a carriage return (CR) or line feed (LF) character followed by a large amount of data without a boundary separator, the parser enters a highly inefficient loop. It repeatedly appends data chunks to an internal buffer and re-scans the entire growing buffer for the boundary. This leads to quadratic complexity in processing time, causing excessive CPU consumption and blocking the worker process, resulting in a denial of service.
Why it matters to the business
An attacker can render web applications and services built on the vulnerable library completely unavailable to legitimate users. This denial of service can disrupt critical business operations, halt customer-facing services, and lead to financial losses and reputational damage. The attack is simple to execute and can be launched by any user, including unauthenticated ones, who can send data to a file upload endpoint.
How an attack unfolds
An attacker targets a web application that uses a vulnerable version of Werkzeug and exposes a file upload endpoint. The attacker constructs a malicious multipart/form-data POST request. The payload for the file upload is crafted to start with a single CR or LF character, followed by megabytes of data that intentionally omits the multipart boundary string. Upon receiving this request, the Werkzeug parser begins its inefficient processing. It appends each chunk of the large file to a buffer and re-scans the entire buffer, consuming significant CPU time. This effectively freezes the worker process, preventing it from handling any other requests and causing a denial of service for the entire application.
How to fix it
Upgrade the Werkzeug library to a patched version. For projects using the 3.x branch, upgrade to version 3.0.1 or later. For projects using the 2.x branch, upgrade to version 2.3.8 or later. If an immediate upgrade is not feasible, consider implementing rate-limiting on file upload endpoints or using a Web Application Firewall (WAF) to block malformed or excessively large multipart requests as a temporary mitigation.
How to confirm the fix worked
To confirm the vulnerability is remediated, check your project's dependencies to ensure Werkzeug is updated to version 3.0.1+ or 2.3.8+. You can verify this using package management tools like `pip list`. To test for exposure in a non-production environment, send a crafted POST request to a file upload endpoint with a payload that starts with a `\r` or `\n` character followed by several megabytes of data without a boundary. A vulnerable system will exhibit a sustained CPU spike for the worker process, while a patched system will handle the request without excessive resource consumption.
Typical attack path
- The attacker identifies a web application using a vulnerable version of the Werkzeug library.
- The attacker locates an endpoint that accepts multipart/form-data, such as a file upload form.
- The attacker crafts a malicious HTTP POST request containing a file upload that starts with a CR or LF character.
- The body of the uploaded file consists of a large volume of data that lacks the expected boundary string.
- The attacker sends this request to the server.
- The server's Werkzeug parser enters a high-CPU loop, causing the worker process to become unresponsive and leading to a denial of service.
How to detect it
Monitor for signs of exploitation by observing web server and application performance metrics. Look for sustained, high CPU utilization (near 100%) in worker processes handling web requests. Correlate these CPU spikes with web server access logs, searching for POST requests to file upload endpoints that result in timeouts (e.g., HTTP 504 Gateway Timeout) or internal server errors (HTTP 500). Application Performance Monitoring (APM) tools may also reveal unusually long-running transactions stuck within Werkzeug's multipart parsing functions.
What your security team should do
- Prioritize patching all applications using the Werkzeug library to versions 3.0.1+ or 2.3.8+.
- Monitor web server and application performance metrics for sustained CPU spikes, which could indicate an ongoing attack.
- If patching is delayed, implement temporary mitigations such as rate-limiting file uploads or deploying WAF rules to inspect and block malformed multipart requests.
The record
Werkzeug is a comprehensive WSGI web application library. In versions on the 3.x branch prior to 3.0.1 and on the 2.x branch prior to 2.3.8, if an upload of a file that starts with CR or LF and then is followed by megabytes of data without these characters: all of these bytes are appended chunk by chunk into internal bytearray and lookup for boundary is performed on growing buffer. This allows an attacker to cause a denial of service by sending crafted multipart data to an endpoint that will parse it. The amount of CPU time required can block worker processes from handling legitimate requests. This vulnerability has been patched in version 3.0.1 and 2.3.8.
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|---|---|---|
| PyPI | werkzeug | 0 | 2.3.8 |
| PyPI | werkzeug | 0 | f3c803b3ade485a45f12b6d6617595350c0f03e2 |
| PyPI | werkzeug | 3.0.0 | 3.0.1 |
| Chainguard | airflow | 0 | 2.9.1-r1 |
| 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 | kubeflow-jupyter-web-app | 0 | 1.8.0-r2 |
| Chainguard | kubeflow-pipelines-visualization-server | 0 | 2.4.0-r0 |
| Chainguard | kubeflow-volumes-web-app | 0 | 1.7.0-r8 |
| Chainguard | py3-supported-werkzeug | 0 | 3.0.1-r0 |
| Chainguard | py3-tensorflow-serving-api | 0 | 2.14.1-r1 |
| Chainguard | py3-werkzeug | 0 | 3.0.1-r0 |
| Chainguard | py3.10-werkzeug | 0 | 3.0.1-r0 |
| Chainguard | py3.11-werkzeug | 0 | 3.0.1-r0 |
| Chainguard | py3.12-werkzeug | 0 | 3.0.1-r0 |
| Chainguard | py3.13-werkzeug | 0 | 3.0.1-r0 |
| Debian:11 | python-werkzeug | 0 | No fix |
| Debian:12 | python-werkzeug | 0 | No fix |
| Debian:13 | python-werkzeug | 0 | 3.0.1-2 |
| Red Hat:openshift:4.12::el8 | cri-o | 0 | 0:1.25.5-2.rhaos4.12.git0217273.el8 |
| Red Hat:openshift:4.12::el8 | cri-o-debuginfo | 0 | 0:1.25.5-2.rhaos4.12.git0217273.el8 |
| Red Hat:openshift:4.12::el8 | cri-o-debugsource | 0 | 0:1.25.5-2.rhaos4.12.git0217273.el8 |
| Red Hat:openshift:4.14::el8 | haproxy | 0 | 0:2.6.13-2.rhaos4.14.el8 |
| Red Hat:openshift:4.14::el8 | haproxy-debugsource | 0 | 0:2.6.13-2.rhaos4.14.el8 |
| Red Hat:openshift:4.14::el8 | haproxy26 | 0 | 0:2.6.13-2.rhaos4.14.el8 |
| Red Hat:openshift:4.14::el8 | haproxy26-debuginfo | 0 | 0:2.6.13-2.rhaos4.14.el8 |
| Red Hat:openshift_ironic:4.12::el9 | python-werkzeug | 0 | 0:2.0.3-5.el9 |
| Red Hat:openshift_ironic:4.12::el9 | python3-werkzeug | 0 | 0:2.0.3-5.el9 |
| Red Hat:openshift_ironic:4.13::el9 | python-werkzeug | 0 | 0:2.0.3-5.el9 |
| Red Hat:openshift_ironic:4.13::el9 | python3-werkzeug | 0 | 0:2.0.3-5.el9 |
| Red Hat:openshift_ironic:4.14::el9 | python-werkzeug | 0 | 0:2.2.3-2.el9 |
| Red Hat:openshift_ironic:4.14::el9 | python3-werkzeug | 0 | 0:2.2.3-2.el9 |
| Red Hat:openstack:17.1::el8 | python-werkzeug | 0 | 0:2.0.1-8.el8ost |
| Red Hat:openstack:17.1::el8 | python3-werkzeug | 0 | 0:2.0.1-8.el8ost |
| Red Hat:openstack:17.1::el9 | python-werkzeug | 0 | 0:2.0.1-6.el9ost |
| Red Hat:openstack:17.1::el9 | python3-werkzeug | 0 | 0:2.0.1-6.el9ost |
| SUSE:Linux Enterprise Module for Python 3 15 SP4 | python-Werkzeug | 0 | 2.3.6-150400.6.6.1 |
| SUSE:Linux Enterprise Module for Python 3 15 SP5 | python-Werkzeug | 0 | 2.3.6-150400.6.6.1 |
| Wolfi | airflow | 0 | 2.9.1-r1 |
| 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 | kubeflow-jupyter-web-app | 0 | 1.8.0-r2 |
| Wolfi | kubeflow-pipelines-visualization-server | 0 | 2.4.0-r0 |
| Wolfi | kubeflow-volumes-web-app | 0 | 1.7.0-r8 |
| Wolfi | py3-supported-werkzeug | 0 | 3.0.1-r0 |
| Wolfi | py3-tensorflow-serving-api | 0 | 2.14.1-r1 |
| Wolfi | py3-werkzeug | 0 | 3.0.1-r0 |
| Wolfi | py3.10-werkzeug | 0 | 3.0.1-r0 |
| Wolfi | py3.11-werkzeug | 0 | 3.0.1-r0 |
| Wolfi | py3.12-werkzeug | 0 | 3.0.1-r0 |
| Wolfi | py3.13-werkzeug | 0 | 3.0.1-r0 |
| openSUSE:Leap 15.4 | python-Werkzeug | 0 | 2.3.6-150400.6.6.1 |
| openSUSE:Leap 15.5 | python-Werkzeug | 0 | 2.3.6-150400.6.6.1 |
| openSUSE:Tumbleweed | python-Werkzeug | 0 | 3.0.1-1.1 |
| pypi | Werkzeug | 3.0 | 3.0.1 |
| pypi | Werkzeug | 3.0.0 | No fix |
Related vulnerabilities
- CVE-2026-27199 Werkzeug is a comprehensive WSGI web application library. Also affects werkzeug
- CVE-2026-21860 Werkzeug is a comprehensive WSGI web application library. Also affects werkzeug
- CVE-2025-66221 Werkzeug safe_join() allows Windows special device names Also affects werkzeug
- CVE-2024-49766 Werkzeug is a Web Server Gateway Interface web application library. Also affects werkzeug
- CVE-2024-49767 Werkzeug is a Web Server Gateway Interface web application library. Also affects werkzeug
- CVE-2016-10516 Cross-site scripting (XSS) vulnerability in the render_full function in debug/tbtools.py… Also affects werkzeug
- CVE-2025-47287 Tornado vulnerable to excessive logging caused by malformed multipart form data Also affects airflow
- CVE-2024-12797 Issue summary: Clients using RFC7250 Raw Public Keys (RPKs) to authenticate a server may… Also affects airflow