DEV Community

CVE Reports
CVE Reports

Posted on Originally published at cvereports.com

CVE-2026-115927: CVE-2026-115927: Event Loop Blocking and Memory Amplification in Tornado Chunked Transfer Encoding Parser

CVE-2026-115927: Event Loop Blocking and Memory Amplification in Tornado Chunked Transfer Encoding Parser

Vulnerability ID: CVE-2026-115927
CVSS Score: 5.3
Published: 2026-10-28

Tornado versions prior to 6.6.0 contain an uncontrolled resource consumption vulnerability (CWE-400) in the HTTP/1.1 chunked transfer encoding parser. When processing incoming chunked payloads that have already buffered in the socket read buffer, Tornado parses chunks in a tight synchronous loop without yielding to the event loop. Furthermore, non-streaming request handlers and SimpleAsyncHTTPClient store each chunk as a discrete Python bytes object inside a list, inducing an approximately 20-fold memory overhead for 1-byte chunks.

TL;DR

An unauthenticated remote attacker can send an HTTP/1.1 request or response with millions of 1-byte chunks to a Tornado server or client (< 6.6.0), monopolizing the Python asyncio event loop and causing approximately 20x memory amplification.


⚠️ Exploit Status: POC

Technical Details

  • CVE ID: CVE-2026-115927 (GHSA-r4j5-9xpp-3985)
  • CWE Classification: CWE-400 (Uncontrolled Resource Consumption) / CWE-770
  • CVSS v3.1 Score: 5.3 Medium (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L)
  • Attack Vector: Network (Unauthenticated HTTP/1.1 Chunked Transfer Encoding)
  • Affected Component: tornado/http1connection.py, httpserver.py, web.py, simple_httpclient.py
  • Security Impact: Process-wide IOLoop starvation and ~20x memory amplification
  • EPSS Score: 0.384% (32.33rd percentile)
  • Patched Version: Tornado 6.6.0

Affected Systems

  • Tornado Web Framework (< 6.6.0)
  • Tornado HTTPServer (< 6.6.0)
  • Tornado SimpleAsyncHTTPClient (< 6.6.0)
  • tornado: < 6.6.0 (Fixed in: 6.6.0)

Code Analysis

Commit: ceab335

Coalesce small chunks and yield periodically in _read_chunked_body, use bytearray for body accumulation, and replace chunk CRLF assert with HTTPInputError.

--- a/tornado/http1connection.py
+++ b/tornado/http1connection.py
@@ -66,6 +66,9 @@
+# Yield to the event loop after processing this many bytes of body data
+_YIELD_THRESHOLD = 256 * 1024
+_CHUNK_YIELD_COST = 1024
...
-        crlf = await self.stream.read_bytes(2)
-        assert crlf == b"\r\n"
+        crlf = await read(self.stream.read_bytes(2))
+        if crlf != b"\r\n":
+            raise httputil.HTTPInputError("improperly terminated chunk")
Enter fullscreen mode Exit fullscreen mode

Exploit Details

  • GitHub: Unit test reproduction in tornado/test/http1connection_test.py (test_chunked_body_tiny_chunks) demonstrating event loop starvation with 1-byte chunks.

Mitigation Strategies

  • Upgrade Tornado to version 6.6.0 or newer to enable periodic event loop yielding and bytearray chunk coalescing.
  • Deploy an upstream HTTP reverse proxy (such as NGINX with proxy_request_buffering enabled) in front of Tornado servers to normalize and buffer incoming chunked requests.
  • Configure strict max_body_size limits on HTTPServer and SimpleAsyncHTTPClient instances to cap maximum per-request resource consumption.
  • Use CurlAsyncHTTPClient instead of SimpleAsyncHTTPClient when making outbound HTTP requests to untrusted third-party servers on Tornado versions prior to 6.6.0.

Remediation Steps:

  1. Audit application dependencies and virtual environments to identify installations of tornado < 6.6.0.
  2. Run pip install --upgrade 'tornado>=6.6.0' and update requirements.txt, pyproject.toml, or lockfiles accordingly.
  3. Verify reverse proxy configurations (e.g., NGINX, AWS ALB, HAProxy) to ensure HTTP request buffering is not disabled unless explicitly required for streaming endpoints.
  4. Restart all Tornado worker processes and services to load the patched library.

References


Read the full report for CVE-2026-115927 on our website for more details including interactive diagrams and full exploit analysis.

Top comments (0)