Cloudanix VulnDB

GHSA-qppv-j76h-2rpx

None

CVSS

—

EPSS

—

Published

Aug 14, 2023

CISA due date

—

Cloudanix analysis

Next patch cycle SSVC: Track

A Python web-server library can misread the size of incoming web requests, which may let someone sneak extra hidden requests past security controls when that library is used together with other web software.

Chainable
Exploitation
Remote Unauthenticated
Attacker needs
None
Complexity
Moderate
Impact
Data Tampering
Component
Web Framework
Class
Improper Input Validation
Remediation
Upgrade
Effort
Medium
Patch risk
Low

What it actually does

Tornado's HTTP/1.1 parser improperly accepts malformed Content-Length values and chunked-transfer sizes (notably numeric fields with a leading plus sign) that stricter parsers reject or interpret differently. When Tornado sits in a multi-parser chain (reverse proxy, load balancer, CDN, or backend), the two implementations disagree on where a request body ends, desynchronizing HTTP framing and enabling request smuggling.

Why it matters to the business

Successful smuggling can bypass front-end authentication or WAF rules, poison caches, hijack another user's session, or reach internal routes the proxy was meant to hide. Ecosystem blast radius is small (about three known downstream dependents), the issue is not on the CISA KEV list, is not tied to ransomware, and has no reported mature public exploit. Residual risk is mainly unpatched internet-facing Tornado services that still terminate or forward HTTP/1.1 more than three years after the August 2023 fix.

How an attack unfolds

An attacker sends HTTP/1.1 traffic whose Content-Length or chunk-size fields Tornado accepts but a paired proxy or backend does not (or interprets with a different body length). Tornado consumes a different number of bytes than the other hop, so leftover data is treated as a new request on the reused connection. That hidden request is processed with the trust, routing, or cache key of the outer connection rather than being inspected by the front end. No named threat actors or campaigns are associated with this issue, and public exploit maturity is none.

How to fix it

Upgrade the tornado PyPI package to 6.3.3 or later, which corrects parsing of Content-Length fields and chunk lengths. Rebuild and redeploy images, wheels, and frozen dependency sets that pin tornado below 6.3.3. Audit requirements.txt, poetry.lock, Pipfile.lock, and transitive dependencies. If an immediate upgrade is not possible, do not place unpatched Tornado in a reverse-proxy or mixed-parser HTTP chain; terminate HTTP at a single consistent parser and limit HTTP/1.1 connection reuse from untrusted clients.

How to confirm the fix worked

Confirm installed and locked tornado versions are 6.3.3 or newer via package metadata and runtime inspection (for example, tornado.version). Search lockfiles and container images for older pins, including transitive copies among the small set of downstream dependents. After upgrade, verify that malformed Content-Length and chunk-size fields are rejected and that legitimate Content-Length and chunked bodies still parse correctly. Re-check architecture so Tornado is not forwarding raw HTTP/1.1 to, or receiving it from, a parser with different framing rules.

Typical attack path

  1. Locate a Tornado service that forwards or receives HTTP/1.1 in a chain with a different parser (proxy, load balancer, CDN, or backend).
  2. Determine how each hop treats borderline Content-Length and chunk-size values.
  3. Send a request whose framing is accepted by one hop and rejected or truncated by the other, causing request-boundary desynchronization on a keep-alive connection.
  4. Have the leftover bytes interpreted as a second, hidden request.
  5. Abuse that smuggled request to bypass access control, poison a cache, or act in another user's session context.

How to detect it

Hunt HTTP access logs, reverse-proxy/load-balancer/CDN logs, and Tornado application logs for HTTP/1.1 requests whose Content-Length value starts with a plus sign, chunk sizes with a leading plus, duplicate or conflicting Content-Length headers, or simultaneous Content-Length and Transfer-Encoding: chunked. Look for keep-alive connections where a backend served a path or header the front end never logged, or where one hop returned 400/502 while the other returned 200, and for cache objects that do not match the front-end request. Because exploit maturity is none and no named actors are reported, treat hits as probing unless correlated with unauthorized access or cache poisoning. Retain raw HTTP logs around anomalies.

  • Content-Length: +
  • Content-Length:+
  • content-length: +
  • content-length:+
  • Transfer-Encoding: chunked

What your security team should do

  • Inventory all tornado usage (direct and transitive) and upgrade to 6.3.3 or later, prioritizing internet-facing HTTP/1.1 proxy or backend roles.
  • Treat remaining unpatched proxying instances as overdue standard patching rather than a KEV emergency; there is no CISA due date and no ransomware association.
  • Map HTTP/1.1 trust boundaries and eliminate mixed-parser chains until every hop is patched.
  • If upgrade is delayed, disable keep-alive from untrusted clients and avoid using Tornado as a reverse proxy.
  • Tune HTTP access and proxy logs to alert on malformed length fields and front-end/back-end request mismatches.

The record

Tornado vulnerable to HTTP request smuggling via improper parsing of `Content-Length` fields and chunk lengths

Affected packages

Ecosystem Package Introduced Fixed
PyPI tornado 0 6.3.3

Related vulnerabilities