Skip to main content

Tornado EUVDEUVD-2026-90655

| CVE-2026-103261 MEDIUM
Allocation of Resources Without Limits or Throttling (CWE-770)
2026-10-01 VulnCheck GHSA-2v9w-f3h6-74rj
6.9
CVSS 4.0 · Vendor: VulnCheck
View

Attack ChainAIDerived

Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain

  1. Access
    Identify internet-facing Tornado endpoint
  2. Delivery
    Craft ~64KB GET with thousands of query fields
  3. Exploit
    Send concurrent unauthenticated requests
  4. Execution
    Synchronous parsing saturates single IOLoop
  5. Impact
    Response times degrade for all clients

Vulnerability Assessment

Weakness
CWE
OWASP Top 10:2025
A06:2025 - Insecure Design
ASVS 5.0
V2 - Validation and Business Logic Resource allocation limits
MITRE ATT&CK

1 technique across 1 tactic: Impact

The technique list with ATT&CK links and the kill-chain view is part of the Basic plan and up.

Exploitation Conditions

No special conditions - remote unauthenticated GET requests against default configurations of any Tornado HTTP server before 6.5.9 trigger the flaw, since HTTPServerRequest.__init__ parses the query string with no field-count limit by default. The only limiting factors are structural, not configuration-based: the query string is bounded by max_header_size (default 65536 bytes, ~7800 short fields per request), and impact is degradation rather than full denial, so an attacker must sustain multiple concurrent high-field requests to meaningfully stall the shared IOLoop. Multi-process/load-balanced deployments dilute the effect per worker; single-process internet-facing Tornado services are most exposed.

Impact

This is a genuine but low-to-moderate priority availability issue. The CVSS 4.0 vector (AV:N/AC:L/AT:N/PR:N/UI:N) confirms remote, low-complexity, unauthenticated exploitation requiring no user interaction, which makes it trivially reachable - but the impact is strictly VA:L (partial availability) with VC:N/VI:N, matching CWE-770 unbounded resource allocation and the description's 'degrade response times' / 'event-loop stalling' language. There is no confidentiality or integrity exposure and no full outage guaranteed, only degradation, so the vendor's 6.9 (4.0) score is driven entirely by easy reachability, not by severe impact. No EPSS score and no KEV listing were provided, and there is no evidence of active exploitation - exploitation status is 'no public exploit identified at time of analysis,' though the GHSA advisory documents a dynamic local reproduction against v6.5.8, so a working trigger is effectively trivial to construct. The attack is also self-limited: Tornado caps the request line plus headers at max_header_size (default 65536 bytes), so a single request carries at most a few thousand short fields (~7800), meaning an attacker must sustain many concurrent requests to meaningfully stall a shared IOLoop rather than achieve a one-shot crash. Net: real and easy to trigger, but bounded impact and no exploitation signals - patch during normal maintenance, prioritize higher for internet-facing single-process Tornado deployments.

Exploit ScenarioDerived

An unauthenticated remote attacker sends GET requests whose query strings are packed with thousands of short key=value pairs (e.g. k0=1&k1=1&...&k7799=1, ~61KB, fitting under the 65536-byte header limit). Tornado parses each synchronously inside its single-threaded IOLoop with no field-count cap, so several such requests in flight burn CPU and delay processing of all other connections on that loop. The GHSA advisory includes a documented local reproduction against v6.5.8, but no weaponized public exploit tool was identified.

This Month Plan within 30 days. Why: MEDIUM severity (CVSS 4.0-6.9).
Patch available 0.5% exploitation probability (EPSS)

Get an e-mail when this CVE is exploited, patched or re-scored. Free account.

Alert me

AnalysisAIv1 – Oct 01, 2026

Unbounded query-string parsing in Tornado before 6.5.9 lets unauthenticated remote attackers stall the event loop of affected servers by sending GET requests whose query strings carry thousands of short parameters. Because HTTPServerRequest.__init__ parses the query string synchronously inside Tornado's single-threaded IOLoop with no field-count cap, a burst of such requests degrades response times for every client sharing that loop rather than triggering a clean crash - impact is availability degradation rated Low (assessed CVSS:3.1 AV:N/AC:L/PR:N/UI:N/C:N/I:N/A:L; vendor CVSS 4.0 base 6.9 with VA:L), and sustained concurrent high-field requests are needed to meaningfully starve other connections. A vendor-released patch exists in Tornado 6.5.9 (upstream PR 3719 / commit 03945136ea9746eccf61caf88edae39642e59c93), and no public exploit code has been identified at time of analysis.

RemediationAI

Upgrade to Tornado 6.5.9 or later, which is the vendor-released fixed version ('pip install -U tornado==6.5.9'); the fix is carried in tornado/httputil.py by upstream PR 3719 (https://github.com/tornadoweb/tornado/pull/3719) and commit 03945136ea9746eccf61caf88edae39642e59c93, and enforcement details plus the advisory text are at https://github.com/tornadoweb/tornado/security/advisories/GHSA-3hv7-mjh2-fv65. If upgrading immediately is not possible, the commit can be backported as a minimal patch (apply the max_num_fields=_DEFAULT_PARSE_BODY_CONFIG.urlencoded.max_arguments argument plus the HTTPInputError wrapper to the HTTPServerRequest query parse) with the trade-off that requests legitimately exceeding the 1000-field limit will begin returning errors. Where code changes are blocked, terminate legacy instances behind a reverse proxy or WAF that rejects or strips query strings with excessive parameter counts or abnormal length (the internal exposure is bounded at roughly 7800 short fields by max_header_size's 65536-byte default, so a front-end cap well below that is a practical filter); lowering Tornado's max_header_size also reduces the field budget but risks breaking clients that send large legitimate headers. Adding per-IP rate limiting and connection concurrency caps buys time against the sustained multi-request pattern needed to stall a shared IOLoop, and running multiple worker processes behind a load balancer spreads the parsing cost across independent event loops so a single hot loop cannot degrade all clients at once. After patching, confirm behavior by sending a request with more than 1000 query fields and verifying Tornado rejects it with an HTTPInputError rather than parsing it.

Affected VersionsENISA

Tornado 0 <6.5.9

Affected Packages

pypi tornado fix: 6.5.9

Source: OSV (Open Source Vulnerabilities)

Affects your stack

Affects 1 package in pypi

Checking this CVE against your own stacks and servers is part of the Basic plan and up.

Technical ContextAI · show details

The defect is a missing resource limit (CWE-770) in Tornado's HTTP request parsing layer. In tornado/httputil.py, HTTPServerRequest.__init__ populated self.arguments via parse_qs_bytes(self.query, keep_blank_values=True); parse_qs_bytes is a thin wrapper around urllib.parse.parse_qs, whose field-count bounding parameter (max_num_fields, added upstream to parse_qsl for exactly this purpose) was simply not passed on the query-string path. Notably, the structurally identical POST-body path in the same file (parse_body_arguments) was hardened in the immediately preceding release 6.5.8 with max_num_fields=config.urlencoded.max_arguments (default 1000), so the maintainers had already judged ~1000 fields the appropriate ceiling for the same urlencoded primitive; the query-string call site was overlooked. Parsing is superlinear enough in field count to be worth bounding, and the work happens synchronously on the IOLoop, so a request line packed with thousands of key=value pairs (for example k0=1&k1=1&...&k7799=1, roughly 61 KB) delays handling of all other connections on that loop. Input is not literally unbounded: the request line plus headers are capped by max_header_size (default 65536 bytes), which permits roughly 7800 short fields per request. The 6.5.9 fix wraps the query parse in a try/except, applies max_num_fields=_DEFAULT_PARSE_BODY_CONFIG.urlencoded.max_arguments via the global parse-body config (HTTPServerRequest has no access to per-connection configuration), and converts oversize input into an HTTPInputError ('Max number of fields exceeded') instead of parsing it. Relevant CPE: cpe:2.3:a:tornadoweb:tornado:*:*:*:*:*:*:*:*.

Know when Tornado gets its next vulnerability

  • Watch products and get an email when something new is published
  • Check this CVE against your own stack and servers
  • Exploit and PoC references, threat intelligence from 22 sources

No credit card · 7-day full trial

Severity by source

Vendor (VulnCheck) PRIMARY 6.9 MEDIUM
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
vuln.today AI 5.3 MEDIUM

Remote, low-complexity, unauthenticated, no interaction; impact is partial availability degradation only (event-loop stalling), with no confidentiality or integrity effect.

3.1 AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L
4.0 AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:L/SC:N/SI:N/SA:N
Red Hat 5.3 MEDIUM

Primary rating from Vendor (VulnCheck).

CVSS VectorVendor: VulnCheck

Attack Vector
Network
Attack Complexity
Low
Attack Requirements
None
Privileges Required
None
User Interaction
None
Vulnerable system: Confidentiality
None
Vulnerable system: Integrity
None
Vulnerable system: Availability
Low
Subsequent system: Confidentiality
None
Subsequent system: Integrity
None
Subsequent system: Availability
None

DescriptionCVE.org

Tornado before 6.5.9 fails to limit the number of query string fields in HTTPServerRequest.__init__, allowing remote attackers to cause event-loop stalling by sending requests with thousands of query parameters. Attackers can send unauthenticated GET requests with unbounded query-string field counts to degrade response times for all clients sharing the same IOLoop.

Threat Intelligence Overview

EPSS Score
0.5%
Top 62% exploitable
Prevalence
High
widely-deployed open-source Python async web framework
Data Quality
4 sources
Confidence: Medium
EUVD NVD CVE.org EPSS Vulnrichment Vendor GitHub

How this decision was reached

The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.

SignalValue
Severity MEDIUM
CISA KEV No
Public POC No
EPSS 0.5%
Patch available Yes
Active threat No
Deciding rule
MEDIUM severity (CVSS 4.0-6.9)
What every action level means
Emergency Immediate action required. Criteria: CRITICAL + in CISA KEV (actively exploited) without patch, OR CRITICAL + EPSS > 30% without patch, OR CRITICAL + active threat signals without patch.
Act Now Prioritize within 24-48h. Criteria: in KEV with patch available, OR CRITICAL + public POC, OR HIGH + EPSS > 10%, OR CRITICAL + active threat, OR any CRITICAL severity.
This Week Schedule remediation this week. Criteria: HIGH severity (CVSS 7.0-8.9). Patch within normal change window.
This Month Plan within 30 days. Criteria: MEDIUM severity (CVSS 4.0-6.9), lower exploitation probability. Include in regular patch cycle.
Monitor Track and reassess. Criteria: LOW severity (CVSS 0.1-3.9), minimal exploitation risk. No immediate action needed.

SSVC AssessmentENISA

SSVC Decision· derived
Scheduled
Exploitation
None
System Exposure· derived
Open
Automatable
Yes
Human Impact· derived
High
Technical Impact
Partial

Priority Score

34
Low Medium High Critical
KEV: 0
EPSS: 0
CVSS: +34
PoC: 0
Weaponized: 0
Threat intel: 0
Gov advisory: 0

Attack Technique

Denial of Service attacks render applications or systems unavailable by overwhelming resources or triggering failure conditions.

CVE-2024-42733 CRITICAL POC
9.8 Mar 07

An issue in Docmosis Tornado v.2.9.7 and before allows a remote attacker to execute arbitrary code via a crafted script

CVE-2023-25266 HIGH POC
8.8 Feb 28

An issue was discovered in Docmosis Tornado prior to version 2.9.5. Rated high severity (CVSS 8.8), this vulnerability i

CVE-2025-67726 HIGH POC
7.5

py3-tornado in Alpine Linux received a security fix packaged as version 6.5.4-r0, addressing an unspecified vulnerabilit

CVE-2023-25265 HIGH POC
7.5 Feb 28

Docmosis Tornado <= 2.9.4 is vulnerable to Directory Traversal leading to the disclosure of arbitrary content on the fil

CVE-2023-25264 HIGH POC
7.5 Feb 28

An issue was discovered in Docmosis Tornado prior to version 2.9.5. Rated high severity (CVSS 7.5), this vulnerability i

CVE-2026-103262 HIGH
8.7 Oct 01

Denial of service in the Tornado web framework's CurlAsyncHTTPClient (all releases before 6.5.9) lets an unauthenticated

CVE-2026-31958 HIGH
8.7 Mar 11

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_s

CVE-2026-91990 HIGH
8.7 Sep 15

Memory amplification denial of service in the Tornado Python web framework before 6.5.8 lets unauthenticated remote atta

CVE-2026-91992 HIGH
8.2 Sep 15

Credential leakage in Tornado's CurlAsyncHTTPClient (all releases through 6.5.6) lets sensitive per-request state — clie

CVE-2026-103263 HIGH
8.2 Oct 01

Unauthenticated local file disclosure in Tornado before 6.5.9 lets remote attackers read files outside a configured stat

CVE-2026-82397 HIGH
7.5 Aug 31

Denial-of-service in Tornado prior to 6.5.8 allows unauthenticated remote attackers to stall the entire server by sendin

CVE-2025-67725 HIGH
7.5

Tornado Python web framework on Alpine Linux received a security fix in package version 6.5.4-r0, addressing an uncharac

Vendor StatusVendor

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy