mediumCVSS 5.3Vulnerability

GHSA-3hv7-mjh2-fv65

## Summary `HTTPServerRequest.__init__` in `tornado/httputil.py` parses the URL query string via `parse_qs_bytes()` with no field-count limit — while the sibling POST-body parsing path (`parse_body_arguments`) received a `max_num_fields=1000` cap added earlier in this exact same release (v6.5.8, commit `8d6363ed`), explicitly to bound parsing cost for the identical underlying primitive. This leaves the query-string path with the resource-exhaustion exposure the body-path fix was meant to close. **File**: `tornado/httputil.py`, line 553 (`HTTPServerRequest.__init__`) ### Root Cause ```python # tornado/httputil.py:553 (before fix) self.arguments = parse_qs_bytes(self.query, keep_blank_values=True) ``` Compare with the POST-body path fixed one commit earlier in the same release: ```python # tornado/httputil.py:1038-1041 uri_arguments = parse_qs_bytes( body, keep_blank_values=True, max_num_fields=config.urlencoded.max_arguments, # default 1000 ) ``` Both call sites funnel through the same `tornado.escape.parse_qs_bytes` (a thin wrapper over `urllib.parse.parse_qs`), which is exactly why `max_num_fields` was added to `urllib.parse.parse_qsl` upstream — to let frameworks bound field count. The fix was applied only to the body path; the query-string path was missed. The request line + headers together are capped at `max_header_size` (default 65536 bytes), so this is not literally unbounded, but a single ~64KB request line can carry thousands of short `key=value` pairs — far beyond the 1000-field limit the maintainer judged appropriate for the structurally identical body case. ### Attack Scenario 1. Attacker sends a `GET` request whose query string is packed with thousands of short fields (e.g. `k0=1&k1=1&...&k7799=1`, ~61KB), fitting comfortably under `max_header_size`. No authentication, cookies, or prior state required. 2. Tornado accepts and parses this with no field-count cap, unlike the equivalent POST-body request (which is correctly r

Properties

severity
medium
summary
Tornado: Unbounded query-string argument count allows event-loop-stalling DoS
cvss_score
5.3
retrieved_at
2026-09-30T23:58:31+00:00
ghsa_published
2026-09-30T23:49:25Z
source_url
https://github.com/advisories/GHSA-3hv7-mjh2-fv65
ghsa_updated
2026-09-30T23:49:26Z
ghsa_id
GHSA-3hv7-mjh2-fv65
last_source
GitHub Advisory Database
cve_id
GHSA-3hv7-mjh2-fv65
cvss_vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L
signal_observed_at
2026-09-30T23:58:31+00:00
is_ghsa_only
true

Related Entities (4)

VULNERABLE_TO (1)

←[Software]pip/tornado

AFFECTS (1)

→[Software]pip/tornado

HAS_WEAKNESS (1)

→[Weakness]Allocation of Resources Without Limits or Throttling

REPORTED_BY (1)

→[Source]GitHub Advisory Database

Explore deeper with Ninja Signal's threat intelligence graph

GHSA-3hv7-mjh2-fv65 (CVSS 5.3) — Ninja Signal Threat Intelligence | Ninja Signal