Skip to content

Tornado: Urlencoded body parsing omits max_num_fields, so one request can stall the event loop

High severity GitHub Reviewed Published Aug 7, 2026 in tornadoweb/tornado

Package

pip tornado (pip)

Affected versions

<= 6.5.7

Patched versions

6.5.8

Description

Summary

Tornado parses application/x-www-form-urlencoded bodies with urllib.parse.parse_qs and does not pass max_num_fields. A body made almost entirely of separators produces tens of millions of fields, and the parse happens on the event loop before the handler runs, so a single request stalls the whole server.

Where it is

tornado/escape.py, at HEAD e530031405e2154654dedc4c84d5656b557ea310:

result = urllib.parse.parse_qs(
    qs, keep_blank_values, strict_parsing, encoding="latin1", errors="strict"
)

max_num_fields is the parameter CPython added for exactly this, and it is absent.

The path to it is entirely server-side and pre-dispatch. RequestHandler._execute parses the body at tornado/web.py:1821, which reaches HTTPServerRequest._parse_body at tornado/httputil.py:636, and the urlencoded branch of parse_body_arguments calls parse_qs_bytes at tornado/httputil.py:1030.

The size that reaches it is bounded only by the body cap, which defaults to the stream's max_buffer_size of 104857600 at tornado/iostream.py:239, applied as the request body default at tornado/http1connection.py:136-140. A 100 MB body of separators is around fifty million fields.

Impact

Denial of service against the whole process, not one request. Tornado is single-threaded and the parse is synchronous on the event loop, so every other connection waits. No authentication is needed if any route accepts a form post, which is the normal case.

Suggested fix

Pass a bound:

result = urllib.parse.parse_qs(
    qs, keep_blank_values, strict_parsing, encoding="latin1", errors="strict",
    max_num_fields=max_num_fields,
)

with a conservative default and a way for applications to raise it. CPython raises ValueError when the limit is exceeded, which maps cleanly onto a 400.

Lowering the default body cap for urlencoded specifically would help too, since 100 MB of form fields is not a shape any real client sends.

Why I do not think this is a duplicate

The published tornado advisories cover out-of-bounds access in the C extension, unbounded accumulation of decompressed chunks in AsyncHTTPClient, the Authorization header surviving cross-origin redirects, credential leakage on curl handle reuse, and cookie attribute validation. The decompression one is the nearest in spirit and is on the client side; this is the server parsing a request body. The call is unchanged at HEAD.

References

@bdarnell bdarnell published to tornadoweb/tornado Aug 7, 2026
Published by the National Vulnerability Database Aug 31, 2026
Published to the GitHub Advisory Database Sep 2, 2026
Reviewed Sep 2, 2026

Severity

High

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Network
Attack complexity
Low
Privileges required
None
User interaction
None
Scope
Unchanged
Confidentiality
None
Integrity
None
Availability
High

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

EPSS score

Exploit Prediction Scoring System (EPSS)

This score estimates the probability of this vulnerability being exploited within the next 30 days. Data provided by FIRST.
(28th percentile)

Weaknesses

Uncontrolled Resource Consumption

The product does not properly control the allocation and maintenance of a limited resource. Learn more on MITRE.

Improper Validation of Specified Quantity in Input

The product receives input that is expected to specify a quantity (such as size or length), but it does not validate or incorrectly validates that the quantity has the required properties. Learn more on MITRE.

CVE ID

CVE-2026-82397

GHSA ID

GHSA-mpf4-983q-p7j4

Source code

Credits

Loading Checking history
See something to contribute? Suggest improvements for this vulnerability.