CVE-2023-25577 Overview
CVE-2023-25577 is a Denial of Service (DoS) vulnerability in Werkzeug, a comprehensive WSGI web application library used extensively in Python web frameworks including Flask. Prior to version 2.2.3, Werkzeug's multipart form data parser will parse an unlimited number of parts, including file parts. Each part, regardless of size, requires CPU time to parse and may consume additional memory as Python data structures.
If a request can be made to an endpoint that accesses request.data, request.form, request.files, or request.get_data(parse_form_data=False), it can cause unexpectedly high resource usage. This allows an attacker to cause a denial of service by sending crafted multipart data to an endpoint that will parse it.
Critical Impact
Attackers can exhaust CPU, memory, and file handles by sending crafted multipart requests with unlimited parts, potentially killing all available worker processes and rendering the application unavailable.
Affected Products
- Palletsprojects Werkzeug versions prior to 2.2.3
- Flask applications using vulnerable Werkzeug versions
- Any Python WSGI application utilizing Werkzeug's multipart form parser
Discovery Timeline
- 2023-02-14 - CVE-2023-25577 published to NVD
- 2024-11-21 - Last updated in NVD database
Technical Details for CVE-2023-25577
Vulnerability Analysis
The vulnerability exists in Werkzeug's multipart form data parser, which is responsible for processing HTTP requests containing multipart/form-data content. This type of content is commonly used for file uploads and form submissions. The parser processes each part of the multipart data individually, allocating CPU cycles and memory for each part encountered.
The core issue is the absence of any limit on the number of parts that can be parsed from a single request. An attacker can craft a malicious request containing thousands or millions of small parts, each requiring individual processing. While each part may be trivially small in bytes, the cumulative effect of parsing numerous parts leads to:
- CPU Exhaustion: Worker processes become blocked parsing malicious requests, unable to handle legitimate traffic
- Memory Exhaustion: Python data structures for each part consume RAM, potentially triggering out-of-memory kills
- File Handle Exhaustion: Unlimited file parts can deplete available file handles
Root Cause
The root cause is CWE-770: Allocation of Resources Without Limits or Throttling. The multipart parser did not enforce any maximum on the number of form or file parts that could be present in a single request. This design oversight allowed resource consumption to scale linearly with the number of parts in a crafted request, without any protective boundaries.
Attack Vector
The attack is network-based and requires no authentication or user interaction. An attacker sends specially crafted HTTP requests with multipart/form-data content type containing an excessive number of small parts to any endpoint that processes form data. The attack can target any endpoint that accesses:
- request.data
- request.form
- request.files
- request.get_data(parse_form_data=False)
When many concurrent malicious requests are sent continuously, this can exhaust or kill all available worker processes, resulting in complete service unavailability.
// Security patch in CHANGES.rst - Merge pull request from GHSA-xg9f-g7g7-2323
the requested size in one ``read`` call. :issue:`2558`
- A cookie header that starts with ``=`` is treated as an empty key and discarded,
rather than stripping the leading ``==``.
+- Specify a maximum number of multipart parts, default 1000, after which a
+ ``RequestEntityTooLarge`` exception is raised on parsing. This mitigates a DoS
+ attack where a larger number of form/file parts would result in disproportionate
+ resource use.
Version 2.2.2
Source: GitHub Commit
Detection Methods for CVE-2023-25577
Indicators of Compromise
- Unusual spikes in CPU or memory utilization on web application servers
- Increased frequency of HTTP requests with multipart/form-data content type containing abnormally large numbers of parts
- Worker process crashes or out-of-memory kills in application logs
- Elevated file handle usage beyond normal operational baselines
Detection Strategies
- Monitor web server access logs for requests with unusually large Content-Length headers or extended processing times on form endpoints
- Implement application-level monitoring for RequestEntityTooLarge exceptions after patching, which may indicate attempted exploitation
- Deploy network-level inspection for HTTP requests with excessive multipart boundaries in the request body
- Configure SIEM rules to alert on patterns of rapid, repeated POST requests to form-handling endpoints
Monitoring Recommendations
- Track worker process health metrics including memory consumption and CPU utilization per request
- Set up alerts for abnormal request parsing durations on endpoints handling file uploads or form submissions
- Monitor application dependency versions to ensure Werkzeug 2.2.3 or later is deployed across all environments
- Implement request rate limiting at the load balancer or reverse proxy level
How to Mitigate CVE-2023-25577
Immediate Actions Required
- Upgrade Werkzeug to version 2.2.3 or later immediately across all environments
- Review and audit all endpoints that process multipart form data for exposure
- Implement rate limiting on form submission and file upload endpoints as a defense-in-depth measure
- Configure max_content_length at the WSGI server or HTTP server level to limit request body sizes
Patch Information
The fix is available in Werkzeug version 2.2.3. The patch introduces a maximum number of multipart parts (default: 1000), after which a RequestEntityTooLarge exception is raised. This effectively limits resource consumption from malicious requests.
For detailed patch information, see the GitHub Security Advisory GHSA-xg9f-g7g7-2323 and the version 2.2.3 release notes.
Additional advisories have been published by Debian (DSA-5470) and NetApp (NTAP-20230818-0003).
Workarounds
- Configure max_content_length at the HTTP server or reverse proxy level to reject excessively large requests before they reach the application
- Implement request timeout configurations to terminate long-running parsing operations
- Deploy a Web Application Firewall (WAF) rule to limit the number of multipart boundaries allowed in request bodies
- Consider implementing custom middleware to count and limit form parts before passing to Werkzeug's parser
# Configuration example - Upgrade Werkzeug using pip
pip install --upgrade werkzeug>=2.2.3
# Verify installed version
pip show werkzeug | grep Version
# For requirements.txt, specify minimum version
echo "werkzeug>=2.2.3" >> requirements.txt
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


