Repository navigation
Releases: ActiveState/tornado
Release list
v5.1.1.post3
Security backport release for the Python 2.7-compatible tornado 5.1.1 line. It backports 18 advisories from Tornado 6.5.3–6.6.0. Each was checked against the 5.1.1 source: all 18 apply to 5.1.1 and all are fixed; none was assessed as not applicable. The release is cumulative: it includes every fix in 5.1.1.1 and 5.1.1+security.2.
Fixed
| Advisory | CVE | Fix |
|---|---|---|
| GHSA-pr2v-jx2c-wg9f | CVE-2025-67724 | Invalid HTTP reason phrases are replaced and escaped (header injection / XSS) |
| GHSA-c98p-7wgm-6p64 | CVE-2025-67725 | Linear-time repeated header lines (quadratic DoS) |
| GHSA-jhmp-mqwm-3gq8 | CVE-2025-67726 | Linear-time header parameter parsing (quadratic DoS) |
| GHSA-3x9g-8vmp-wqvf | CVE-2026-49853 | SimpleAsyncHTTPClient strips Authorization/Cookie/credentials on cross-origin redirects |
| GHSA-cx3h-4qpv-8hc9 | CVE-2026-49854 | tornado.speedups validates the websocket mask length (out-of-bounds read) |
| GHSA-mgf9-4vpg-hj56 | CVE-2026-49855 | max_body_size enforced on the decompressed size |
| GHSA-mpf4-983q-p7j4 | CVE-2026-82397 | 1000-argument limit on urlencoded bodies |
| GHSA-pw6j-qg29-8w7f | — | CurlAsyncHTTPClient resets curl handles before reuse (credential leak) |
| GHSA-8423-8fgw-73vq | — | Multipart part limit applied before splitting the body |
| GHSA-3hv7-mjh2-fv65 | — | 1000-argument limit on query strings |
| GHSA-c2m8-h5v5-343r | — | StaticFileHandler doesn't follow symlinks out of the static root (allowed_symlink_directory opts in) |
| GHSA-chx6-46f5-w4vp | — | CurlAsyncHTTPClient gains max_body_size (100MB) and a bounded streaming buffer |
| GHSA-wwv5-g3v4-889x | — | Every set_cookie keyword attribute is validated (capitalized kwargs bypass) |
| GHSA-c6v4-qj2h-f748 | — | set_cookie max_age goes through int() (attribute injection) |
| GHSA-pw9p-v7r6-gx4p | — | RedirectHandler substitutions can't change the scheme or host (open redirect) |
| GHSA-pcg2-g6cj-q92c | — | Obsolete header line folding is rejected (quadratic DoS) |
| GHSA-r4j5-9xpp-3985 | — | Body reading yields to the IOLoop and coalesces tiny chunks (event-loop starvation) |
| GHSA-v8g8-cp5j-42fg | — | static_url validates paths, reads only regular files, caps size, and bounds its cache |
Other security improvements (no advisory)
max_body_sizeis enforced on read-until-close responses.- At most 10
1xxresponses are accepted. - A gzip body with trailing data no longer hangs the IOLoop.
- Multi-member gzip is decoded in full, and truncated gzip is rejected.
- Websocket reads yield to the IOLoop, and only the latest ping is answered.
- Valueless header parameters (
*_no_context_takeover) are honored.
Behavior changes
Most of these fixes reject input that was previously accepted:
- Folded headers get a 400 or 599.
- More than 1000 query or body arguments are rejected.
- The curl client refuses responses over 100MB decompressed.
- Symlinks out of the static root get a 403.
static_url("../x")raises a 403.- Trailing or truncated gzip is rejected.
data_receivedpieces no longer follow chunk boundaries.
CurlAsyncHTTPClient needs libcurl ≥ 7.81, and ≥ 7.83.0 for CVE-2026-49853 redirect stripping. Full details are in docs/releases/v5.1.1.post3.rst.
Verification
Tested on Python 2.7.18 with tornado.speedups built, and with pycurl 7.43.0.5 against libcurl 8.17.0:
- The targeted suite passes: 820 tests, 10 skipped.
- The sdist and wheel metadata say
5.1.1.post3.
v5.1.1+security.2
Security backport release for the Python 2.7-compatible tornado 5.1.1 line. Of nine reported advisories, one was already fixed (5.1.1.1) and two collapse into one fix, giving seven backports (one commit each).
- CVE-2024-52804 (GHSA-8w49-h785-mj3c): O(n^2) cookie unquoting replaced with a single regex — DoS.
- CVE-2025-47287 (GHSA-7cx3-6m66-7c5m): malformed multipart bodies raise once instead of logging per part — log-flood DoS.
- CVE-2026-31958 (GHSA-qjxf-f2mg-c6mc): multipart part count (1000) and per-part header size (10 KiB) are now capped — DoS.
- CVE-2026-35536 (GHSA-fqwm-6jpj-5wxc, GHSA-78cv-mqj4-43f7):
set_cookievalidates name/domain/path/samesite attributes (control chars, DEL,;) — attribute injection. - GHSA-753j-mpmx-qq6g: reject both-Transfer-Encoding-and-Content-Length / duplicate or unknown Transfer-Encoding, and strip only RFC 7230 OWS from header values — request smuggling.
- GHSA-qppv-j76h-2rpx: strict (digits-only) Content-Length and chunk-size parsing — request smuggling.
- GHSA-w235-7p84-xx57: reject bare CR/LF in outgoing request headers (curl + HTTP/1 writer) — header injection.
Already fixed in 5.1.1.1: GHSA-hj3f-6gcp-jg8j (CVE-2023-28370, StaticFileHandler open redirect).
Behavior notes: the multipart caps (tornado.httputil._MULTIPART_MAX_PARTS / _MULTIPART_MAX_PART_HEADER_SIZE) and stricter multipart rejection are behavior changes.
PR: #1
Tornado 5.1.1.1
ActiveState release of Tornado version 5.1.1.1
This is a Python 2 patch version to close CVE-2023-28370.