Cloudanix VulnDB

CVE-2025-54121

Medium · 5.3

CVSS

5.3

EPSS

0.7%

Published

Jul 21, 2025

CISA due date

—

Cloudanix analysis

Next patch cycle SSVC: Track

A flaw in some Python web services can let someone slow or temporarily disrupt the site by sending unusually large file uploads.

Exploitation
Remote Unauthenticated
Attacker needs
None
Complexity
Low
Impact
Denial Of Service
Component
Web Framework
Class
Denial of service
Remediation
Upgrade
Effort
Medium
Patch risk
Low

What it actually does

Starlette versions 0.47.1 and earlier can block the ASGI event loop while parsing multipart/form-data uploads when an uploaded file grows beyond the in-memory spool threshold and is rolled over to disk. Because the rollover path performs blocking disk I/O on the main event loop thread, a remote unauthenticated client can submit large multipart file uploads that tie up the worker handling the request. The flaw does not provide code execution, data disclosure, or data modification, but it can reduce availability by preventing the application from accepting or processing other connections while the event loop is blocked.

Why it matters to the business

Internet-facing Python services built on affected Starlette versions may become slow or temporarily unavailable if attackers or abusive clients send large file-upload requests. The operational impact is most relevant for APIs and web applications that expose multipart upload endpoints, especially where upload size limits, request timeouts, reverse-proxy buffering, or worker isolation are weak. The issue is not in CISA KEV, is not known to be ransomware-associated, has low EPSS, and has no reported mature public exploit, so prioritization should be risk-based; however, the fix is straightforward and should be included in normal dependency patch cycles, with expedited handling for public upload-heavy services.

How an attack unfolds

An attacker first identifies a Starlette-based endpoint that accepts multipart/form-data, such as a file upload, form submission, or API route that calls request.form() or otherwise parses uploaded files. The attacker then sends one or more unauthenticated HTTP POST requests containing files large enough to exceed Starlette's default in-memory spool size. In affected versions, Starlette begins handling the upload in memory and then performs a rollover to disk in a way that blocks the main event loop. While that blocking disk operation is occurring, the ASGI worker cannot promptly accept new connections or service unrelated requests. By repeating or parallelizing these oversized multipart uploads, an attacker can cause elevated latency, worker starvation, request timeouts, and partial denial of service without needing credentials or user interaction.

How to fix it

Upgrade Starlette to version 0.47.2 or later. For source-based deployments using the encode/starlette repository, ensure the code includes commit 6ee94f2cac955eeae68d2898a8dec8cf17b48736 or a later release containing the same fix. Rebuild and redeploy applications and containers that vendor or indirectly depend on Starlette, including frameworks that may pin Starlette transitively. As defense in depth, enforce maximum request body sizes at the edge proxy or load balancer, set strict per-endpoint file-size limits, apply request and idle timeouts, limit concurrent uploads per client, use sufficient ASGI worker processes, and monitor event-loop lag. If immediate upgrade is not possible, restrict public access to upload endpoints, require authentication where feasible, and reject multipart requests above a safe threshold before they reach the application.

How to confirm the fix worked

Confirm dependency resolution shows Starlette 0.47.2 or later in the deployed runtime, not only in source control. For Python deployments, check package metadata using commands such as `python -m pip show starlette`, `python -m pip freeze`, `poetry show starlette`, or the equivalent SBOM/container scan. Verify containers and serverless artifacts were rebuilt after the dependency update. Exercise upload endpoints in a staging environment with multipart files above the spool threshold and confirm the service remains responsive to concurrent lightweight requests. Review reverse-proxy, WAF, and application configuration to ensure body-size limits and timeouts are active. If using source checkouts, verify the Starlette tree contains commit 6ee94f2cac955eeae68d2898a8dec8cf17b48736 or a later fixed revision.

Typical attack path

  1. Discover an exposed Starlette/FastAPI-style web service with endpoints that accept multipart form submissions or file uploads.
  2. Send HTTP POST requests using Content-Type: multipart/form-data with file parts large enough to exceed the upload spool threshold.
  3. Trigger Starlette's UploadFile rollover from memory to disk during multipart parsing.
  4. Cause blocking disk I/O on the event loop thread, delaying unrelated request handling on the same worker.
  5. Repeat the requests or open multiple concurrent uploads to amplify latency, connection failures, and temporary service unavailability.

How to detect it

Look for evidence of availability-focused abuse rather than compromise artifacts. Relevant sources include reverse-proxy access logs, WAF logs, CDN logs, ASGI server logs, application logs, APM traces, host metrics, and container orchestration events. Hunt for bursts of POST requests using Content-Type: multipart/form-data, especially to upload or form endpoints, with large request bodies, long request durations, client disconnects, gateway timeouts, or worker restarts. Correlate these with CPU wait, disk I/O spikes, event-loop lag, rising open connections, and elevated 408/499/500/502/503/504 responses. Because this flaw does not normally create persistent files or execute commands, absence of filesystem or process IOCs does not rule out exploitation. Stronger evidence is a time-correlated pattern of oversized multipart uploads causing ASGI worker timeouts or degraded availability.

  • Content-Type: multipart/form-data
  • multipart/form-data
  • POST
  • request body too large
  • client intended to send too large body
  • upstream timed out
  • upstream prematurely closed connection
  • worker timeout
  • WORKER TIMEOUT
  • timeout waiting for application response
  • Application startup complete
  • ClientDisconnect
  • starlette.requests.ClientDisconnect
  • TemporaryFile
  • SpooledTemporaryFile
  • /tmp/tmp
  • HTTP/1.1" 408
  • HTTP/1.1" 499
  • HTTP/1.1" 502
  • HTTP/1.1" 503
  • HTTP/1.1" 504

What your security team should do

  • Inventory externally reachable Python ASGI applications and identify those using Starlette 0.47.1 or earlier, including transitive use through higher-level frameworks.
  • Prioritize upgrade to Starlette 0.47.2 or later for public services with file-upload, multipart form, media, document, import, or attachment endpoints.
  • Add or verify edge controls: maximum request body size, upload rate limiting, connection limits, request timeouts, and per-client throttling.
  • Monitor application performance telemetry for event-loop lag, worker timeouts, spikes in multipart POST volume, and abnormal upload sizes.
  • Create detection rules for repeated large multipart/form-data POST requests followed by 5xx, 408, 499, 502, 503, or 504 responses.
  • If patching is delayed, temporarily restrict upload endpoints to authenticated users, trusted networks, or lower file-size limits.
  • Ensure dependency scanning covers both direct and transitive Starlette installations in source repositories, container images, and deployed artifacts.

The record

Starlette is a lightweight ASGI (Asynchronous Server Gateway Interface) framework/toolkit, designed for building async web services in Python. In versions 0.47.1 and below, when parsing a multi-part form with large files (greater than the default max spool size) starlette will block the main thread to roll the file over to disk. This blocks the event thread which means the application can't accept new connections. The UploadFile code has a minor bug where instead of just checking for self._in_memory, the logic should also check if the additional bytes will cause a rollover. The vulnerability is fixed in version 0.47.2.

Affected packages

Ecosystem Package Introduced Fixed
PyPI starlette 0 0.47.2
Chainguard airflow-3 0 3.0.3-r3
Chainguard airflow-3-bitnami-compat 0 3.0.3-r3
Chainguard airflow-3-compat 0 3.0.3-r3
Chainguard airflow-3-iamguarded-compat 0 3.0.3-r3
Chainguard airflow-core-3 0 3.0.3-r2
Chainguard airflow-core-3-compat 0 3.0.3-r2
Chainguard airflow-core-3-oci-entrypoint 0 3.0.3-r2
Chainguard k8s-sidecar 0 1.31.0-r1
Chainguard kserve 0 0.16.0-r5
Chainguard kserve-agent 0 0.16.0-r5
Chainguard kserve-agent-compat 0 0.16.0-r5
Chainguard kserve-manager 0 0.16.0-r5
Chainguard kserve-manager-compat 0 0.16.0-r5
Chainguard kserve-qpext 0 0.16.0-r5
Chainguard kserve-qpext-compat 0 0.16.0-r5
Chainguard kserve-router 0 0.16.0-r5
Chainguard kserve-router-compat 0 0.16.0-r5
Chainguard kserve-storage-controller 0 0.16.0-r5
Chainguard mlflow 0 3.1.4-r0
Chainguard mlflow-bitnami 0 3.1.4-r0
Chainguard mlflow-iamguarded-compat 0 3.1.4-r0
Chainguard nemo 0 2.3.2-r3
Chainguard open-webui 0 0.6.18-r1
Chainguard open-webui-compat 0 0.6.18-r1
Chainguard py3.10-vllm-cuda-11.8 0 0.9.2-r2
Chainguard py3.10-wheels-vllm-cuda-11.8 0 0.9.2-r2
Chainguard reflex 0 0.8.3-r0
Debian:11 starlette 0 No fix
Debian:12 starlette 0 No fix
Debian:13 starlette 0 0.46.1-3
Debian:14 starlette 0 0.46.1-3
Wolfi airflow-3 0 3.0.3-r3
Wolfi airflow-3-bitnami-compat 0 3.0.3-r3
Wolfi airflow-3-compat 0 3.0.3-r3
Wolfi airflow-3-iamguarded-compat 0 3.0.3-r3
Wolfi k8s-sidecar 0 1.31.0-r1
Wolfi kserve 0 0.16.0-r5
Wolfi kserve-agent 0 0.16.0-r5
Wolfi kserve-agent-compat 0 0.16.0-r5
Wolfi kserve-manager 0 0.16.0-r5
Wolfi kserve-manager-compat 0 0.16.0-r5
Wolfi kserve-qpext 0 0.16.0-r5
Wolfi kserve-qpext-compat 0 0.16.0-r5
Wolfi kserve-router 0 0.16.0-r5
Wolfi kserve-router-compat 0 0.16.0-r5
Wolfi kserve-storage-controller 0 0.16.0-r5
Wolfi mlflow 0 3.1.4-r0
Wolfi mlflow-bitnami 0 3.1.4-r0
Wolfi mlflow-iamguarded-compat 0 3.1.4-r0
Wolfi open-webui 0 0.6.18-r1
Wolfi open-webui-compat 0 0.6.18-r1
Wolfi reflex 0 0.8.3-r0
openSUSE:Leap 15.6 python-starlette 0 0.35.1-150600.3.6.1
openSUSE:Leap 16.0 python-starlette 0 0.41.3-160000.3.1
openSUSE:Tumbleweed python-starlette 0 0.47.2-1.1

Related vulnerabilities