CVE-2025-54121 Overview
CVE-2025-54121 affects Starlette, a lightweight Asynchronous Server Gateway Interface (ASGI) framework used to build async web services in Python. Versions 0.47.1 and below contain a flaw in the multipart form upload handler. When the framework parses a file larger than the default spool size, it performs a synchronous disk rollover on the main event loop thread. This blocks the event loop and prevents the application from accepting new connections. The issue is tracked as a resource management flaw [CWE-770] and is fixed in version 0.47.2.
Critical Impact
Remote unauthenticated attackers can stall the ASGI event loop by uploading large multipart files, denying service to all concurrent users of the application.
Affected Products
- Starlette ASGI framework versions 0.47.1 and below
- Python web applications using Starlette's UploadFile for multipart form parsing
- Downstream frameworks built on Starlette, including FastAPI
Discovery Timeline
- 2025-07-21 - CVE-2025-54121 published to the National Vulnerability Database
- 2026-04-15 - Last updated in NVD database
Technical Details for CVE-2025-54121
Vulnerability Analysis
Starlette uses Python's SpooledTemporaryFile to buffer multipart upload data. The spool keeps small files entirely in memory and rolls over to disk once the configured threshold is exceeded. The rollover operation performs synchronous file system I/O. Starlette's UploadFile implementation invokes this rollover from coroutine code without offloading it to a worker thread.
When a request body exceeds the spool size, the disk write executes directly on the asyncio event loop. The event loop is single-threaded, so this blocks every other coroutine, including connection acceptors and request handlers. Concurrent users experience stalled responses until the write completes. An attacker who sends multiple large uploads can sustain denial of service against the application.
Root Cause
The bug lives in the UploadFile.write logic inside starlette/datastructures.py. The code branches on whether the file is currently held in memory through the self._in_memory flag. The check does not account for the case where the next chunk will push the cumulative size past the rollover threshold. As a result, the synchronous rollover triggered by SpooledTemporaryFile runs inline on the event loop instead of being dispatched to a thread executor. See the GitHub Security Advisory GHSA-2c2j-9gv5-cj73 for the full advisory text.
Attack Vector
The vulnerability is reachable over the network without authentication or user interaction. Any Starlette endpoint that accepts multipart/form-data uploads is exposed. An attacker submits an HTTP request whose file part exceeds the default spool threshold. The server begins parsing, hits the rollover branch, and blocks the event loop for the duration of the disk write. Repeated or concurrent uploads compound the effect and prevent the server from servicing legitimate traffic.
No proof-of-concept exploit code is required beyond a standard HTTP client capable of sending a large multipart body. Review the vulnerable code in datastructures.py and the fix commit for technical details.
Detection Methods for CVE-2025-54121
Indicators of Compromise
- Spikes in HTTP request latency or worker timeouts on Starlette or FastAPI services accepting file uploads.
- Repeated multipart/form-data requests from a single source with content lengths well above the default spool size.
- ASGI worker processes showing high wall-clock time but low CPU utilization during upload handling.
Detection Strategies
- Inventory Python applications and identify deployments running Starlette <= 0.47.1 or FastAPI versions that pin a vulnerable Starlette release.
- Instrument the event loop with asyncio debug mode or middleware that logs coroutines exceeding a latency threshold.
- Inspect web application firewall and reverse proxy logs for clusters of large multipart POST requests targeting upload endpoints.
Monitoring Recommendations
- Alert on sustained increases in p95/p99 request latency on endpoints that accept uploads.
- Track connection queue depth and worker saturation on ASGI servers such as Uvicorn and Hypercorn.
- Correlate upload size distributions against historical baselines to surface anomalous traffic patterns.
How to Mitigate CVE-2025-54121
Immediate Actions Required
- Upgrade Starlette to version 0.47.2 or later across all environments.
- For FastAPI deployments, update to a release that depends on a patched Starlette version, or pin Starlette directly.
- Audit upload endpoints and enforce maximum request body size limits at the reverse proxy or ingress layer.
Patch Information
The fix landed in Starlette 0.47.2. The patch adjusts the rollover check inside UploadFile to account for the size of the incoming chunk and offloads the rollover to a thread executor when triggered. Review the upstream commit 9f7ec2e and the maintainer's discussion thread for implementation notes.
Workarounds
- Restrict the maximum request body size at the proxy layer (for example, client_max_body_size in nginx) to a value below the spool threshold.
- Configure rate limiting on multipart upload endpoints to limit the volume an attacker can submit.
- Disable or gate upload endpoints with authentication where they are not required for unauthenticated users.
# Pin the fixed Starlette release
pip install "starlette>=0.47.2"
# Verify the installed version
python -c "import starlette; print(starlette.__version__)"
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


