Cloudanix VulnDB

CVE-2026-31958

High · 7.5

CVSS

7.5

EPSS

0.4%

Published

Mar 11, 2026

CISA due date

—

Cloudanix analysis

Next patch cycle SSVC: Track

A website or API using affected Tornado versions can be knocked offline by specially crafted form-upload requests that overload its request handling.

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

Tornado versions prior to 6.5.5 can synchronously parse multipart/form-data request bodies containing an excessive number of parts. Because multipart parsing occurs on the main event-loop thread and the effective constraint is primarily max_body_size, an unauthenticated remote client can submit a request that stays within the configured body-size limit but contains many multipart boundaries and fields, consuming CPU and blocking normal request handling. The result is high availability impact for Tornado-based services, not code execution or data disclosure.

Why it matters to the business

A vulnerable Tornado application can be made slow or unavailable by relatively simple network requests, potentially disrupting customer-facing APIs, internal web services, upload workflows, and dependent business processes. The issue is not listed in CISA KEV, is not known to be used in ransomware campaigns, and has low current EPSS, but internet-exposed Tornado services remain at risk because exploitation does not require authentication or user interaction.

How an attack unfolds

An attacker first identifies an HTTP endpoint served by a vulnerable Tornado version that accepts or attempts to parse multipart/form-data. They then craft one or more POST requests with a Content-Type of multipart/form-data and a very large number of small parts, keeping the total body size at or below the server's max_body_size threshold. When Tornado receives the request, it parses the multipart body synchronously on the main thread. The parsing cost blocks the event loop, delaying or preventing the application from processing other connections. Repeating the request or sending concurrent requests can cause sustained service degradation or denial of service until the traffic stops, the process is restarted, rate limits are applied, or Tornado is upgraded.

How to fix it

Upgrade Tornado to version 6.5.5 or later wherever it is used directly or pulled in as a transitive dependency. If immediate upgrade is not possible, reduce exposure by placing strict request limits in front of Tornado: enforce a low maximum multipart part count at a reverse proxy, WAF, API gateway, or application middleware; restrict multipart/form-data to endpoints that truly require it; apply per-IP and per-route rate limits; lower max_body_size where feasible; require authentication for upload endpoints; and reject requests with suspiciously high boundary or part counts before they reach Tornado. These mitigations reduce risk but should not be treated as a substitute for upgrading.

How to confirm the fix worked

Confirm all deployed Python environments, containers, virtual environments, lockfiles, and build artifacts use Tornado 6.5.5 or later. Validate with package inventory commands such as `python -m pip show tornado`, `python -m pip freeze`, dependency lockfile review, software composition analysis, and container image scans. Exercise upload or multipart endpoints in a staging environment with high-part-count multipart requests and verify the service rejects or limits them without event-loop stalls, CPU spikes, or health-check failures. Also confirm upstream proxies or gateways enforce expected body-size, part-count, and rate-limit controls before requests reach the application.

Typical attack path

  1. Discover a Tornado-based HTTP service, especially one exposing file upload, form submission, API ingestion, or webhook endpoints.
  2. Identify endpoints that accept POST, PUT, or PATCH requests with multipart/form-data bodies.
  3. Generate a multipart/form-data payload with many small parts and repeated boundaries while staying within the configured maximum request body size.
  4. Send the payload to the vulnerable endpoint, optionally using concurrent connections or repeated requests.
  5. Cause Tornado to spend excessive CPU time parsing the multipart body synchronously on the main thread.
  6. Observe elevated latency, worker saturation, failed health checks, connection timeouts, or service unavailability.

How to detect it

Review HTTP access logs, reverse proxy logs, WAF logs, API gateway logs, APM traces, and host/container metrics for evidence of prior multipart abuse. Focus on time windows with unexplained CPU spikes, event-loop latency, request queue growth, elevated response times, health-check failures, worker restarts, or increased 5xx/timeout responses. Look for repeated POST, PUT, or PATCH requests with `Content-Type: multipart/form-data`, large request bodies near configured limits, unusually high counts of multipart boundaries, many small form fields, abnormal upload attempts to endpoints that do not normally receive multipart traffic, and concentration from a small set of source IPs or user agents. Correlate suspicious requests with application logs showing slow request processing, proxy timeout errors, autoscaling events, container OOM/restarts, or service unavailability. There are no known public threat actors or ransomware campaigns tied to this vulnerability in the supplied data, so detection should be behavior-based rather than actor- or malware-signature-based.

  • Content-Type: multipart/form-data
  • boundary=
  • POST
  • PUT
  • PATCH
  • multipart/form-data; boundary=
  • 408
  • 429
  • 499
  • 500
  • 502
  • 503
  • 504
  • upstream timed out
  • request timed out
  • client intended to send too large body
  • max_body_size
  • HTTPServerRequest(protocol=
  • tornado.application
  • tornado.httpserver
  • tornado.httputil

What your security team should do

  • Inventory all applications, containers, and serverless packages using Tornado and prioritize internet-facing services and endpoints accepting multipart/form-data.
  • Upgrade Tornado to 6.5.5 or later and rebuild/redeploy affected artifacts from clean dependency lockfiles.
  • Add compensating controls at the edge: WAF or gateway rules for excessive multipart boundaries or form parts, route-specific request body limits, and per-source rate limiting.
  • Review upload and form-handling endpoints to ensure multipart/form-data is accepted only where required and preferably after authentication.
  • Monitor for CPU saturation, event-loop blocking, latency spikes, 408/429/499/500/502/503/504 responses, and bursts of large or unusual multipart POST requests.
  • Include this scenario in load and abuse testing so high-part-count multipart requests are rejected quickly and do not block the Tornado main thread.

The record

Tornado is a Python web framework and asynchronous networking library. In versions of Tornado prior to 6.5.5, the only limit on the number of parts in multipart/form-data is the max_body_size setting (default 100MB). Since parsing occurs synchronously on the main thread, this creates the possibility of denial-of-service due to the cost of parsing very large multipart bodies with many parts. This vulnerability is fixed in 6.5.5.

Affected packages

Ecosystem Package Introduced Fixed
Chainguard airflow-2 0 2.11.2-r1
Chainguard airflow-3 0 3.1.8-r2
Chainguard dask-kubernetes 0 2026.3.0-r1
Chainguard kubeflow-pipelines-visualization-server 0 2.16.0-r2
Chainguard litellm 0 1.81.14-r1
Chainguard tensorflow-cpu-jupyter 0 2.21.0-r1
Chainguard tensorflow-gpu-jupyter 0 2.21.0-r1
SUSE:Linux Enterprise High Performance Computing 15 SP4-ESPOS python-tornado6 0 6.3.2-150400.9.15.1
SUSE:Linux Enterprise High Performance Computing 15 SP4-LTSS python-tornado6 0 6.3.2-150400.9.15.1
SUSE:Linux Enterprise High Performance Computing 15 SP5-ESPOS python-tornado6 0 6.3.2-150400.9.15.1
SUSE:Linux Enterprise High Performance Computing 15 SP5-LTSS python-tornado6 0 6.3.2-150400.9.15.1
SUSE:Linux Enterprise Module for Python 3 15 SP7 python-tornado6 0 6.3.2-150400.9.15.1
SUSE:Linux Enterprise Server 15 SP4-LTSS python-tornado6 0 6.3.2-150400.9.15.1
SUSE:Linux Enterprise Server 15 SP5-LTSS python-tornado6 0 6.3.2-150400.9.15.1
SUSE:Linux Enterprise Server 15 SP6-LTSS python-tornado6 0 6.3.2-150400.9.15.1
SUSE:Linux Enterprise Server for SAP Applications 15 SP4 python-tornado6 0 6.3.2-150400.9.15.1
SUSE:Linux Enterprise Server for SAP Applications 15 SP5 python-tornado6 0 6.3.2-150400.9.15.1
SUSE:Linux Enterprise Server for SAP Applications 15 SP6 python-tornado6 0 6.3.2-150400.9.15.1
Wolfi airflow-3 0 3.1.8-r2
Wolfi dask-kubernetes 0 2026.3.0-r1
Wolfi kubeflow-pipelines-visualization-server 0 2.16.0-r2
Wolfi tensorflow-cpu-jupyter 0 2.21.0-r1
openSUSE:Leap 15.6 python-tornado6 0 6.3.2-150400.9.15.1
openSUSE:Leap 16.0 python-tornado6 0 6.5-160000.4.1
openSUSE:Leap 16.0 salt 0 3006.0-160000.5.1
openSUSE:Leap 16.0 salt-test 0 3006.0-160000.5.1
openSUSE:Tumbleweed python-tornado6 0 6.5.5-1.1
openSUSE:Tumbleweed salt 0 3006.0-56.1

Related vulnerabilities