CVE-2025-54121 Overview
CVE-2025-54121 is a Denial of Service vulnerability affecting Starlette, a lightweight ASGI (Asynchronous Server Gateway Interface) framework/toolkit designed for building async web services in Python. The vulnerability exists in versions 0.47.1 and below, where parsing a multi-part form with large files (greater than the default max spool size) causes Starlette to block the main thread while rolling the file over to disk. This blocking behavior prevents the event loop from processing new connections, effectively rendering the application unavailable.
Critical Impact
Applications using Starlette for file uploads become unresponsive when processing large files, as the main event loop is blocked during disk write operations, preventing all new connection handling.
Affected Products
- Starlette versions 0.47.1 and below
- Python applications using Starlette's UploadFile functionality
- Frameworks built on Starlette (e.g., FastAPI) that handle multi-part form uploads
Discovery Timeline
- 2025-07-21 - CVE CVE-2025-54121 published to NVD
- 2025-07-22 - Last updated in NVD database
Technical Details for CVE-2025-54121
Vulnerability Analysis
The vulnerability stems from a logic error in the UploadFile class within Starlette's datastructures.py module. When handling multi-part form uploads, Starlette uses Python's SpooledTemporaryFile to manage file data. Files are initially held in memory, but when they exceed a configurable threshold (_max_size), the data is "rolled over" to disk storage.
The flaw occurs because the UploadFile code only checks whether the current data is in memory (self._in_memory), but fails to evaluate whether incoming additional bytes will trigger a rollover. This synchronous disk write operation blocks the async event loop, which is the core mechanism Python ASGI applications use to handle concurrent connections. During this blocking period, no new connections can be accepted, and existing connections may time out.
Root Cause
The root cause is classified as CWE-770: Allocation of Resources Without Limits or Throttling. The UploadFile implementation performs blocking I/O operations within the async event loop context without checking if pending data will exceed memory thresholds and require disk rollover. The missing preemptive check for future memory usage allows the blocking condition to occur unexpectedly.
Attack Vector
An attacker can exploit this vulnerability remotely over the network without authentication. The attack involves sending crafted multi-part form requests with file uploads sized to trigger the rollover threshold. By timing multiple requests appropriately, an attacker can keep the event loop blocked, causing a sustained denial of service condition. The attack requires minimal complexity and no user interaction.
self.size = size
self.headers = headers or Headers()
+ # Capture max size from SpooledTemporaryFile if one is provided. This slightly speeds up future checks.
+ # Note 0 means unlimited mirroring SpooledTemporaryFile's __init__
+ self._max_mem_size = getattr(self.file, "_max_size", 0)
+
@property
def content_type(self) -> str | None:
return self.headers.get("content-type", None)
Source: GitHub Commit Record
The patch adds preemptive capture of the _max_size attribute from the SpooledTemporaryFile during initialization, enabling future checks to determine if incoming data will cause a rollover before it happens.
Detection Methods for CVE-2025-54121
Indicators of Compromise
- Application becomes unresponsive during multi-part file upload requests
- Event loop thread shows high blocking time in application performance monitoring
- Connection timeouts increase during periods of file upload activity
- Server logs show request queue buildup with upload-related endpoints
Detection Strategies
- Monitor async event loop blocking metrics using Python profiling tools like asyncio.get_event_loop().slow_callback_duration
- Implement application-level health checks that detect event loop starvation
- Review dependency manifests for Starlette versions <= 0.47.1
- Use SentinelOne Singularity to detect anomalous resource consumption patterns on application servers
Monitoring Recommendations
- Configure alerting for sustained connection timeout rates on upload endpoints
- Monitor Python process thread states for prolonged blocking I/O operations
- Track the ratio of pending to processed connections during upload operations
- Deploy application performance monitoring (APM) with async-aware instrumentation
How to Mitigate CVE-2025-54121
Immediate Actions Required
- Upgrade Starlette to version 0.47.2 or later immediately
- Audit applications built on Starlette-based frameworks (FastAPI, etc.) and update dependencies
- Implement rate limiting on file upload endpoints as a temporary protective measure
- Consider adding a reverse proxy with request timeout configurations
Patch Information
The vulnerability is fixed in Starlette version 0.47.2. The fix modifies the UploadFile class to capture the _max_size attribute from SpooledTemporaryFile during initialization, enabling the code to check if additional incoming bytes will cause a rollover before performing blocking disk operations. Detailed patch information is available in the GitHub Security Advisory and the commit record.
Workarounds
- Implement upload size limits at the reverse proxy or load balancer level to reduce large file exposure
- Use an external file upload service that handles file processing outside the main application event loop
- Deploy request queuing with worker processes separate from the ASGI event loop
- Configure aggressive connection and request timeouts to minimize blocking impact
# Configuration example: Update Starlette via pip
pip install --upgrade starlette>=0.47.2
# Verify installed version
pip show starlette | grep Version
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


