CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



GHSA-8423-8FGW-73VQ

GHSA-8423-8FGW-73VQ: Memory Amplification Denial of Service in Tornado Multipart Form Parser

Alon Barad
Alon Barad
Software Engineer

Sep 2, 2026·6 min read·16 visits

Executive Summary (TL;DR)

Unauthenticated remote Denial of Service in Tornado's multipart parser due to memory and CPU amplification occurring before verification of max_parts limits, leading to Out-of-Memory crashes.

GHSA-8423-8FGW-73VQ is a pre-authentication denial of service vulnerability in the Tornado web server's handling of multipart/form-data. The flaw allows an unauthenticated remote attacker to cause memory exhaustion and CPU starvation by transmitting a crafted HTTP request containing a high density of boundary delimiters. Because Tornado splits the entire request body in memory prior to enforcing the max_parts validation threshold, the Python interpreter attempts to materialize a massive list of byte segments. This triggers an immediate memory exhaustion (OOM) crash or server-wide CPU starvation before the payload can be validated and rejected.

Vulnerability Overview

The Tornado web framework utilizes the parse_multipart_form_data function inside its httputil module to process incoming multipart/form-data payloads. This function is exposed across any endpoint accepting file uploads or complex multi-part forms. The primary task of this parser is to segment the raw HTTP request body into discrete, manageable blocks using a boundary delimiter string supplied in the Content-Type header.

To safeguard against resource exhaustion attacks, Tornado permits administrators to enforce a max_parts constraint, which defaults to 1000. Under normal conditions, requests exceeding this threshold are immediately rejected. However, a structural control flow issue exists because the parser completes the partitioning of the entire input buffer before verifying the number of resulting segments against the configured limit.

An attacker can exploit this operational sequence by crafting a payload containing a extremely dense distribution of boundary delimiters. By utilizing a single-character boundary string, the attacker forces the underlying Python engine to execute a complete buffer split and allocate millions of individual transient byte slices. This allocation occurs in the pre-validation phase, consuming all available system memory and causing process termination.

Root Cause Analysis

The underlying technical flaw lies in the algorithmic execution order of tornado.httputil.parse_multipart_form_data. When a client initiates a multipart request, Tornado reads the raw byte stream and searches for the terminal boundary indicator using a reverse search (rfind). Once identified, the engine invokes Python's native bytes.split() method to partition the input stream.

Python's built-in bytes.split() executes a linear scan of the entire target memory buffer to locate all instances of the specified delimiter. For every match found, CPython allocates a new byte slice object and appends its reference to a dynamically growing list. This intensive memory allocation phase occurs entirely within the runtime environment before control returns to Tornado's validation logic.

Because the list is fully materialized in-memory before Tornado checks the number of components, the protection mechanism is bypassed during the critical allocation phase. A small 600KB request body containing 100,000 artificial boundaries will force the system to instantiate 100,000 distinct list items. If scaled to a larger payload such as 100MB, the system attempts to process roughly 17.5 million list elements, leading to a complete depletion of system RAM.

Code Analysis

The vulnerable logic is located within tornado/httputil.py. In affected versions, the parsing sequence was structured as follows:

# Vulnerable code path in affected versions of tornado/httputil.py
def parse_multipart_form_data(
    boundary: bytes, data: bytes, arguments: Dict[str, List[bytes]], files: Dict[str, List[ObjectDict]], config: Optional[HttpRequestConfig] = None
) -> None:
    ...
    final_boundary_index = data.rfind(b"--" + boundary + b"--")
    if final_boundary_index == -1:
        raise HTTPInputError("Invalid multipart/form-data: no final boundary found")
    
    # Vulnerable split operation: processes entire stream with no limit
    parts = data[:final_boundary_index].split(b"--" + boundary + b"\r\n")
    
    # Limit validation: occurs after memory has already been exhausted
    if len(parts) > config.max_parts:
        raise HTTPInputError("multipart/form-data has too many parts")

The vulnerability was resolved in commit de85b3f87446e323e881bbaa3d5a74f4b76e5f05 by passing an explicit limit to the split() function:

# Patched code path in tornado/httputil.py
    # The split depth is restricted to config.max_parts + 1
    parts = data[:final_boundary_index].split(
        b"--" + boundary + b"\r\n", config.max_parts + 1
    )

By specifying config.max_parts + 1 as the maxsplit parameter, the Python interpreter halts the buffer scan and terminates partitioning immediately after reaching the limit. The remaining unparsed segment is left intact as the final entry in the list, ensuring that total list allocations never exceed config.max_parts + 2 elements. This hard ceiling prevents uncontrolled heap consumption.

Attack Methodology and Proof-of-Concept

Exploitation of GHSA-8423-8FGW-73VQ requires no authentication and can be completed through a single crafted HTTP POST request. The attacker targets any application route configured to handle multipart form submissions. To maximize amplification efficiency, the attacker overrides the multipart boundary parameter in the Content-Type header to a single character, such as x.

The attacker then generates a payload containing a dense sequence of delimiter bytes. For a boundary designated as x, the required delimiter search pattern is b"--" + b"x" + b"\r\n". A single arbitrary byte is positioned between each delimiter, creating a highly compressed payload:

POST /upload HTTP/1.1
Host: target-server.local
Content-Type: multipart/form-data; boundary=x
Content-Length: 600005
 
q--x
q--x
... [repeated 100,000 times] ...
--x--

When the Tornado parser encounters this payload, the built-in split() method executes and instantly materializes 100,000 Python byte slice objects. Under concurrent conditions, or when scaled to larger request sizes, the rapid surge in memory allocations exhausts the host's physical RAM, forcing the operating system kernel's Out-of-Memory (OOM) killer to terminate the web server process.

Impact Assessment

The operational impact of this vulnerability is a complete Denial of Service (DoS) affecting web application availability. Because Tornado relies on an asynchronous, single-threaded event loop structure, blocking operations or process crashes immediately terminate service for all active and pending client connections.

While this issue does not facilitate remote code execution or expose sensitive application data, it represents a highly effective disruption vector. In containerized environments such as Docker or Kubernetes, the depletion of container memory limits will trigger automatic pod restarts, leading to a continuous state of instability if the attack is sustained.

No specialized exploitation tools or privileges are needed to launch this attack. The presence of public proof-of-concept scripts combined with the pre-authentication nature of the vulnerability creates a low barrier to entry for prospective threat actors seeking to degrade service availability.

Remediation and Mitigation Guidance

The recommended remediation path is to upgrade Tornado to version 6.5.8 or higher. This version implements the restricted maxsplit logic, preventing memory amplification.

If immediate upgrading is not possible, security teams should implement perimeter defensive controls. Web Application Firewalls (WAFs) or reverse proxies (such as Nginx) can be configured to block requests that contain suspiciously short boundary strings in the Content-Type header. Standard browsers generate long, random boundary hashes, so rejecting boundaries shorter than 8 characters is a safe and reliable filter.

# Example Nginx configuration to restrict request body sizes on upload endpoints
client_max_body_size 2M;

Additionally, restricting the maximum permitted body size for multipart requests limits the raw volume of delimiters an attacker can submit, effectively capping the potential amplification factor.

Official Patches

TornadoOfficial patch implementing early restriction on split limits in httputil.py

Fix Analysis (1)

Technical Appendix

CVSS Score
5.3/ 10
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N

Affected Systems

Tornado Web Server

Affected Versions Detail

Product
Affected Versions
Fixed Version
tornado
tornadoweb
< 6.5.86.5.8
AttributeDetail
CWE IDCWE-400
Attack VectorNetwork
CVSS Score5.3
EPSS ScoreNot Available
ImpactDenial of Service (DoS)
Exploit StatusPoC Available
KEV StatusNot Listed

MITRE ATT&CK Mapping

T1499.004Endpoint Denial of Service: Application Exhaustion Flood
Impact
CWE-400
Uncontrolled Resource Consumption

The program does not properly control the allocation and maintenance of a key resource, allowing an actor to construct a request designed to consume excessive resources.

Known Exploits & Detection

GitHub GistProof of Concept script demonstrating memory amplification via the split-before-count vulnerability in Tornado's httputil parser.

Vulnerability Timeline

Proof of Concept exploit published on GitHub Gist by researcher afldl.
2026-07-31
Official patch committed to the Tornado repository by maintainer Ben Darnell.
2026-08-05
Tornado version 6.5.8 released containing the security fix.
2026-09-01
Security advisory GHSA-8423-8fgw-73vq published to the GitHub Advisory Database.
2026-09-01

References & Sources

  • [1]GHSA-8423-8fgw-73vq Security Advisory
  • [2]Tornado Fix Commit
  • [3]Tornado Release v6.5.8
  • [4]Exploit Proof of Concept Gist

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•8 days ago•CVE-2026-87697
8.8

CVE-2026-87697: Untrusted Deserialization in .NET PresentationCore Clipboard Handling

A remote code execution vulnerability exists in Microsoft .NET due to untrusted data deserialization within the PresentationCore component. The flaw stems from implicit auto-conversion flags during clipboard data retrieval operations.

Alon Barad
Alon Barad
30 views•5 min read
•8 days ago•CVE-2026-70007
8.8

CVE-2026-70007: Out-of-Bounds Write Vulnerability in .NET Framework and WPF Subsystem

An out-of-bounds write vulnerability in Microsoft .NET Framework, .NET runtime, and Visual Studio allows unauthenticated remote attackers to execute arbitrary code via crafted pixel-shader bytecode or auto-converted clipboard payloads.

Amit Schendel
Amit Schendel
18 views•6 min read
•9 days ago•CVE-2026-70186
7.5

CVE-2026-70186: ASP.NET Core Denial of Service Vulnerability via Framework Deadlock

ASP.NET Core contains a thread deadlock vulnerability (CWE-833) that allows an unauthenticated remote attacker to cause a denial of service over the network by exhausting server thread pool resources.

Amit Schendel
Amit Schendel
16 views•5 min read
•9 days ago•CVE-2026-70035
8.8

CVE-2026-70035: Insecure Deserialization Remote Code Execution in Microsoft .NET Framework and .NET Runtime

CVE-2026-70035 is a high-severity Remote Code Execution (RCE) vulnerability in Microsoft .NET Framework, .NET runtime, and Visual Studio caused by improper handling during the deserialization of untrusted data (CWE-502). An unauthenticated attacker can execute arbitrary code within the context of the affected process by delivering a crafted serialized payload.

Amit Schendel
Amit Schendel
23 views•6 min read
•9 days ago•CVE-2026-70183
7.5

CVE-2026-70183: Elevation of Privilege in ASP.NET Core and Visual Studio via Concurrent Race Condition

An elevation of privilege vulnerability exists in ASP.NET Core and Microsoft Visual Studio due to improper synchronization during concurrent thread execution. Authenticated remote attackers with low privileges can exploit a timing window to manipulate shared resources and assume higher-level execution contexts.

Alon Barad
Alon Barad
20 views•5 min read
•12 days ago•CVE-2026-107844
5.3

CVE-2026-107844: Path Traversal Vulnerability in Contao ImagesController

A path traversal vulnerability (CWE-22) in Contao CMS allows unauthenticated remote attackers to bypass directory boundary restrictions in ImagesController and access files within the project directory.

Amit Schendel
Amit Schendel
23 views•5 min read