A deceptively small parsing flaw in the popular Python WSGI utility library Werkzeug can be turned into a powerful denial-of-service weapon: specially crafted multipart/form-data uploads that start with a carriage return (CR) or line feed (LF), followed by megabytes of data without additional CR/LF bytes, drive the library’s multipart parser into pathological CPU and memory use — enough to block workers, exhaust memory, and take services offline. This behavior was tracked as CVE-2023-46136 and has been patched upstream, but the vulnerability’s operational impact, inconsistent severity scoring across vendors, and wide reuse of Werkzeug inside products and vendor stacks make it a practical availability risk that deserves close attention from developers, maintainers, and infrastructure teams.
Werkzeug is a widely used Python WSGI utility library maintained by the Pallets Projects group; it provides request/response handling, routing helpers, and core HTTP conveniences that many frameworks and internal components reuse. The library’s multipart parser is responsible for handling HTTP file uploads encoded as multipart/form-data. Multipart parsing is inherently tricky: the parser must detect boundaries and process incoming data that can arrive in arbitrarily sized chunks, which makes code efficiency and incremental algorithms essential.
CVE-2023-46136 identifies an algorithmic complexity / uncontrolled resource consumption issue in Werkzeug’s multipart processing. When a file part uploaded in a multipart body begins with CR (0x0D) or LF (0x0A) and then continues with a large run of bytes that contain no CR/LF, the parser’s boundary-detection logic appends each incoming chunk into an internal bytearray and repeatedly searches for partial boundaries on the growing buffer. The repeated scanning of a growing buffer with no helpful delimiter causes CPU usage to spike and memory consumption to balloon, producing a denial-of-service condition against any endpoint that parses such input. Multiple vulnerability databases and vendor advisories document the issue and the upstream fix.
This type of parser-driven DoS is not unique to Werkzeug. Similar multipart and parser issues have repeatedly produced availability bugs in other ecosystems when incremental parsing logic fails to handltly — an operational pattern WindowsForum readers will recognize from prior multipart/HTTP parsing and media-parsing DoS incidents.
Remaining risks and caveats:
CVE-2023-46136 is not an obscure corner case: it’s a reminder that availability is a core security property. Treat multipart parsers and any library that touches untrusted input with skepticism, patch promptly, and apply bounding controls so a single malformed request cannot bring your service to its knees.
Source: MSRC Security Update Guide - Microsoft Security Response Center
Background / Overview
Werkzeug is a widely used Python WSGI utility library maintained by the Pallets Projects group; it provides request/response handling, routing helpers, and core HTTP conveniences that many frameworks and internal components reuse. The library’s multipart parser is responsible for handling HTTP file uploads encoded as multipart/form-data. Multipart parsing is inherently tricky: the parser must detect boundaries and process incoming data that can arrive in arbitrarily sized chunks, which makes code efficiency and incremental algorithms essential.CVE-2023-46136 identifies an algorithmic complexity / uncontrolled resource consumption issue in Werkzeug’s multipart processing. When a file part uploaded in a multipart body begins with CR (0x0D) or LF (0x0A) and then continues with a large run of bytes that contain no CR/LF, the parser’s boundary-detection logic appends each incoming chunk into an internal bytearray and repeatedly searches for partial boundaries on the growing buffer. The repeated scanning of a growing buffer with no helpful delimiter causes CPU usage to spike and memory consumption to balloon, producing a denial-of-service condition against any endpoint that parses such input. Multiple vulnerability databases and vendor advisories document the issue and the upstream fix.
This type of parser-driven DoS is not unique to Werkzeug. Similar multipart and parser issues have repeatedly produced availability bugs in other ecosystems when incremental parsing logic fails to handltly — an operational pattern WindowsForum readers will recognize from prior multipart/HTTP parsing and media-parsing DoS incidents.
What the vulnerability actually is (technical summary)
The root cause, in plain terms
- The multipart parser tries to detect the next boundary by searching for newline sequences (CR/LF) that typically separate parts.
- If the uploaded part begins with CR or LF and the remainder of that part contains no CR or LF for a long stretch, the code continuously appends incoming chunks into a single growing buffer.
- For each appended chunk, the parser executes a lookup for the boundary in the entire buffer rather than using a more efficient incremental or streaming-safe approach.
- The repeated full-buffer scanning makes CPU cost roughly proportional to the square of the number of chunks processed in the pathological case and causes rapid memory growth as the buffer expands — a classic algorithmic complexity DoS (ACD) pattern.
Why this matters operationally
- A single crafted request can saturate a worker thread/process’ CPU and memory. If the application is single-threaded or uses a small worker pool, a few such requests can exhaust capacity and deny service to legitimate users.
- If multiple connections exploit the same condition concurrently, operator-level controls like health-checkers or orchestrator restarts may not stop the service from recurring failure if the underlying code remains unpatched.
- The speculative risk: depending on hosting and orchestration settings, such resource exhaustion can prompt OOM killers, orchestrator health cycles, and cascading failures across services.
Who and which versions are affected
Multiple vendor advisories and vulnerability databases converge on the same general set of affected versions and the patched releases:- Affected: Werkzeug releases prior to the upstream fixes — commonly reported as versions older than 2.3.8 and 3.0.0 versions prior to 3.0.1. The vulnerability entry points to parsing code present across several 2.x and early 3.0.x releases.
- Patched: Upstream fixes were included in Werkzeug 2.3.8 and Werkzeug 3.0.1 (and later). The NVD and advisory databases list 3.0.1 as a definitive patched release; other vendor advisories and package trackers also list 2.3.8 as a supported patched branch. Operators should upgrade to the latest available patched release in whichever major line they run.
Severity and scoring: why different sources disagree
CVE-2023-46136 has been assigned varying severity ratings by different authorities:- NVD and several Linux distributors list a CVSS v3.1 vector with a Base Score in the high range (commonly 7.5) due to its ability to cause complete availability loss and because the attack can be mounted over a network with no privileges.
- Several vulnerability aggregators and security trackers mentioned a lower numeric score (for example, 5.7 in some listings), reflecting alternative assumptions about attack complexity and required privileges.
- Differences in CVSS scoring stem from how analysts set attributes like Attack Vector, Privileges Required, User Interaction, and Scope. If the assessor treats the vector as requiring local or authenticated access, the numeric score will drop; if it’s judged to be network-exploitable with no privileges required for product deployments (common for many exposed HTTP endpoints), the score rises.
- Operational context matters: if a product embeds Werkzeug only in administrative UIs protected by authentication, the effective risk to public users is reduced; conversely, if it’s used by an unauthenticated, internet-facing API, the risk is higher.
Evidence of product impact and vendor responses
Several vendors included this CVE in product advisories and published remediation steps:- Oracle documented the issue as impacting multiple Oracle Communications components that use Werkzeug and assigned a CVSS v3.1 Base Score of 7.5 for their products, emphasizing the ease of remote exploitation in their contexts. Oracle’s CPU listings treat this as an availability-impacting flaw in affected components.
- IBM and appliance vendors that embed Werkzeug in dashboards or management planes (for example, IBM Storage Ceph dashboards) published security bulletins referencing CVE-2023-46136 and advised upgrading packages or product versions. Downstream vendors sometimes indicate the fix is included in specific product releases rather than calling for a direct Werkzeug upgrade by end users.
- Distributors such as Red Hat and SUSE categorized the issue as important/high and issued packages or guidance for the affected distribution builds. SUSE’s advisory mirrors NVD’s description and score.
How to detect exploitation and vulnerable deployments
Detecting an active exploit or a vulnerable component requires a combination of inventory, logs, and runtime observation.- Inventory the Python environment and dependency graph:
- Identify services and Python packages that import Werkzeug either directly or via frameworks (Flask historically bundles Werkzeug components and many internal tools re-import parts). Check installed package versions (pip freeze, package manifests, container image manifests).
- Search logs and metrics for anomalous multipart uploads:
- Look for unusually long POST bodies to endpoints that accept file uploads.
- Spike patterns: sustained high CPU on worker processes handling multipart/form-data requests.
- Memory growth traces (process memory climbing steadily during single request processing).
- Web server and WSGI server metrics:
- Worker hang behavior (requests stuck in request-handling state for very long durations).
- Exited or restarted workers due to OOM kills correlated with multipart POST patterns.
- Network-level detection:
- Long TCP connections carrying upload payloads with few CR/LF occurrences — some network capture tooling can flag bodies that are mostly single-byte runs without expected delimiters.
Mitigations and immediate response steps
If you maintain or operate Python web applications, follow this prioritized remediation checklist:- Upgrade first
- Upgrade Werkzeug to a patched release: 2.3.8 or 3.0.1 (or newer). Prefer the latest micro/patch release in your major stream. Upstream advisories and NVD indicate these releases include the fix. Confirm the version in your deployed environments.
- Patch vendor products
- If you run commercial appliances or vendor-managed products (Oracle Communications, IBM Storage, NetApp, etc.), follow the vendor’s security bulletin and apply the product patch or firmware update they provide. Vendor packaging may bundle different Werkzeug builds and will have product-specific remediations.
- Apply runtime mitigations while patching
- Enforce request size limits at the web server or reverse proxy layer. Limit maximum upload size aggressively for endpoints that don’t genuinely require large uploads.
- Implement request timeouts and connection limits that abort unusually long-running uploads.
- Use WAF rules to detect and block multipart bodies that begin with CR/LF and contain unusually long runs without CR/LF — many WAFs support custom rules that can spot suspicious byte patterns.
- Rate-limit upload requests per client IP or per user account to reduce the impact of repeated attempts.
- Run parsing in isolated worker pools: dedicate a limited set of workers to handle untrusted uploads, so resource exhaustion cannot trivially bring down unrelated request processing workers.
- Code-level mitigations
- If you cannot immediately upgrade, consider defensive wrappers that pre-parse or validate the incoming Content-Type and Content-Length and drop suspicious requests before invoking Werkzeug’s multipart parser.
- Consider using lower-level frameworks that stream and bound reads rather than buffering large bodies into memory when processing uploads.
- Operational improvements
- Improve dependency management and software bill of materials (SBOM) practices so that embedded libraries like Werkzeug can be quickly identified across systems.
- Regularly scan container images and packages using SBOM-aware scanners and vulnerability feeds to detect vulnerable transitive dependencies.
Patching guidance and practical notes
- For Python projects using pip or poetry: update your dependency constraints to require Werkzeug >= 2.3.8 or >= 3.0.1 and rebuild your environment or container images. Re-run test suites that exercise multipart upload endpoints.
- For OS/distribution packages: apply the vendor-provided updates (Debian, Red Hat, SUSE). Distribution packages may backport fixes into older package versions; follow the distribution advisory rather than assuming only the upstream version numbers matter.
- For vendor appliances or products: consult the vendor security bulletin and apply the provided product update. Some vendors provide workarounds or mitigations for customers who can’t immediately install a full product upgrade.
- Verify that multipart uploads of benign files still work and that file integrity is preserved.
- Exercise multipart boundary edge cases in a controlled test environment to ensure the fix corrects the pathological CPU/memory behavior.
- Monitor worker CPU and memory during sustained uploads to confirm the absence of escalation.
Code-level explanation and suggested engineering fixes
At a technical level, robust multipart parsers should:- Use streaming and incremental algorithms that search for boundaries only in a small sliding window rather than rescanning a growing buffer.
- Maintain state that allows detection of partial boundaries across chunk boundaries without repeatedly scanning the entire buffer.
- Enforce upper limits on the size of an individual part and allocate memory in bounded chunks or use temporary files for very large parts.
- Prefer deterministic linear-time algorithms (KMP-like partial-match scanning or incremental state automata) instead of naive repeated full-buffer lookups.
Detection, logging, and forensics: what to collect
If you suspect exploitation, collect:- WSGI server logs with request and response timings.
- Worker process CPU and memory metrics (historical telemetry helps correlate spikes).
- Web server reverse-proxy logs showing content lengths and request durations.
- If available, packet captures or application-layer traces showing the multipart upload’s structure (note: handle PII carefully).
- Orchestrator events (k8s pod restarts, OOM kill reasons, health-check failures).
- Repeated POSTs to upload endpoints with large Content-Length and long durations.
- Requests showing a short leading sequence (CR or LF) followed by a long single-run body (this is the attack signature).
- Correlation between request arrivals and worker CPU spikes or OOM events.
Broader lessons and the supply-chain angle
CVE-2023-46136 reinforces several persistent themes in modern software security and operations:- Parser complexity is an enduring source of availability risk. Small edge cases in parsing logic — especially for network-facing input — repeatedly lead to DoS or worse if not coded defensively.
- Algorithmic complexity attacks are easy to craft and hard to mitigate purely via signature-based detection. Defenders need parsing algorithms with provable worst-case behavior and practical limits.
- Open-source libraries are widely reused in vendors’ products; an upstream flaw can ripple into commercial appliances and cloud services. Vendor advisories that map CVEs to product lines (Oracle, Red Hat, IBM, etc.) are necessary reading for operators.
- Robust SBOM and dependency-tracking practices greatly reduce time-to-detection and remediation when transitive dependencies are involved.
Responsible disclosure and timeline (brief)
CVE-2023-46136 was publicly disclosed in October 2023; upstream patches were released in subsequent point releases (2.3.8 and 3.0.1). Vendors and distributors published follow-up advisories and product-specific fixes. While the vulnerability’s exploitability is straightforward to reproduce in lab settings, there are no widely reported, automated exploit campaigns tied to this CVE in public feeds at present — but the condition is trivial enough that opportunistic abuse is feasible. Treat any unpatched endpoint as high-risk until it’s patched or mitigated.Recommended action plan for teams (step-by-step)
- Inventory:
- Locate all services and containers that include Werkzeug. Check SBOMs, pip freeze outputs, container manifests, and vendor product packaging.
- Prioritize:
- Put internet-facing endpoints and public APIs that accept file uploads at the highest patch priority.
- Patch:
- Upgrade to Werkzeug >= 2.3.8 or >= 3.0.1 where applicable. Apply vendor updates for commercial products.
- Hardening:
- Enforce upload size limits, connection timeouts, and WAF rules to reduce attack surface.
- Monitor:
- Enable alerting for long-running uploads, worker CPU spikes, and OOM kills.
- Test and validate:
- Run regression and load tests to confirm fixes don’t break legitimate upload workflows.
- Document and rehearse:
- Add this class of parser DoS into incident response runbooks and post-incident reviews.
Final assessment: strengths, remaining risks, and a cautionary note
The good news: this CVE is well-understood, and upstream fixes are available. Vendors and distributions have published advisories and patches, and established defensive controls (request size limits, WAF rules, worker isolation) can materially reduce exposure while upgrades roll out.Remaining risks and caveats:
- Many products bundle Werkzeug inside larger stacks and may not expose di users; operators must rely on vendor updates for appliances and managed services.
- Deployments that cannot be patched immediately remain susceptible; operators should apply layered mitigations and monitor aggressively.
- Because the attack is trivial to construct — and because parsing bugs are an attractive “easy win” for attackers — unpatched, internet-accessible endpoints represent an unacceptable operational risk.
CVE-2023-46136 is not an obscure corner case: it’s a reminder that availability is a core security property. Treat multipart parsers and any library that touches untrusted input with skepticism, patch promptly, and apply bounding controls so a single malformed request cannot bring your service to its knees.
Source: MSRC Security Update Guide - Microsoft Security Response Center