Skip to content
Threat Feed
low advisory

Denial of Service in Tornado via Unbounded Form Field Parsing

Tornado fails to restrict the number of fields parsed in application/x-www-form-urlencoded request bodies, allowing an unauthenticated attacker to cause a denial-of-service by stalling the event loop.

CVE search metadata

CVE search record: CVE-2026-82397. Severity: high. CVSS: 7.5. EPSS: 0.35%. KEV: no. Product: Tornado (<= 6.5.7). Brief: Denial of Service in Tornado via Unbounded Form Field Parsing. Brief link: https://feed.craftedsignal.io/briefs/2026-09-tornado-dos/

Tornado versions 6.5.7 and earlier are vulnerable to a denial-of-service (DoS) condition due to how they process application/x-www-form-urlencoded request bodies. The web framework utilizes urllib.parse.parse_qs to decode incoming form data but fails to implement the max_num_fields parameter introduced in CPython. Because Tornado is single-threaded and executes this parsing synchronously on the event loop before reaching the application handler, an attacker can send a crafted request body containing tens of millions of field separators. This forces the server process to expend significant CPU cycles on parsing, effectively stalling the event loop and blocking all other concurrent connections. The issue is exacerbated by the default 100 MB request body limit, which provides ample space for an attacker to include roughly fifty million fields in a single HTTP POST request. This vulnerability is pre-dispatch and requires no authentication, making it a critical risk for internet-facing Tornado applications.

Attack Chain

  1. Attacker identifies an internet-facing endpoint running a vulnerable Tornado version that accepts POST requests with application/x-www-form-urlencoded content.
  2. Attacker crafts a malicious HTTP POST request body consisting of a large sequence (up to 100 MB) of delimiter characters (e.g., ampersands) to maximize the number of fields.
  3. The request is transmitted to the target Tornado server.
  4. The Tornado HTTP server reads the full request body up to the configured max_buffer_size (default 100 MB).
  5. The server executes tornado.web.RequestHandler._execute, which triggers the synchronous _parse_body routine within the event loop.
  6. The parse_qs_bytes function attempts to parse the unbounded number of fields using urllib.parse.parse_qs without a limit.
  7. The process consumes high CPU while parsing the millions of fields, causing the event loop to hang and ceasing all processing of other legitimate client connections.
  8. The server remains in an unresponsive state until the malicious parsing completes or the process is manually restarted.

Impact

Successful exploitation results in a complete denial-of-service for the affected Tornado server process. Since the event loop is blocked synchronously, all legitimate users of the service will experience timeouts or connection resets. This affects any application running on Tornado that accepts POST requests, which is standard for web services, and can be executed by any unauthenticated remote attacker.

Recommendation

  1. Upgrade to a version of Tornado that includes a fix for CVE-2026-82397 (future release beyond 6.5.7).
  2. Implement an application-level wrapper or middleware to validate the size and complexity of request bodies before they reach the framework's parser.
  3. Review and reduce the max_buffer_size and request body limits for routes that do not require 100 MB of form data to mitigate the maximum possible input size for the parser.

Immediate actions

Patch Tornado to 6.5.8 or later

Application Security 48h

Mitigations

Reduce the default body buffer size (max_buffer_size) in the Tornado application configuration to a reasonable limit for expected traffic.

immediate IT Operations

CVE-2026-82397