Tornado: Incomplete fix for CVE-2026-35536: cookie attribute injection re-opened via the legacy case-insensitive `**kwargs` path in `set_cookie`
Summary
The CVE-2026-35536 fix added a validation loop that rejects [\x00-\x20\x3b\x7f], but only for the
hardcoded lowercase keys name/domain/path/samesite. The still-live deprecated **kwargs path
writes attacker-supplied attribute values straight into the Morsel with no validation, and because
Morsel.__setitem__ is case-insensitive, a capitalized kwarg (Domain=, Path=, SameSite=, Max-Age=)
routes to the same reserved attribute while bypassing the loop — re-opening ;-delimited attribute injection.
self.set_cookie("sid", "abc", Domain="evil.com; Secure; SameSite=None")
# -> Set-Cookie: sid=abc; Domain=evil.com; Secure; SameSite=None; Path=/
# Sanity (the canonical lowercase named arg IS blocked):
self.set_cookie("sid", "abc", domain="evil.com; Secure") # -> http.cookies.CookieError
The patch's regression test (SetCookieForbiddenCharHandler) only exercises the four named params, never the
**kwargs path, so the gap is not regression-covered.
Affected code
tornado/web.py→RequestHandler.set_cookie: the validation loop covers only the lowercase named args; the trailingif kwargs:loop doesmorsel[k] = vwith no character validation.
Steps to reproduce
GET /upper (uses Domain= kwarg) emits Set-Cookie: c_upper=v; Domain=evil.com; Secure; SameSite=None; Path=/; GET /lower (uses lowercase
domain=) returns a CookieError.
Impact
Injection of independent cookie attributes (force/drop Secure/HttpOnly/SameSite, rebind Domain/Path)
— the same impact CVE-2026-35536 closed, via the sibling path the patch missed. Conditional on the app using
a capitalized/legacy keyword.
Suggested remediation
Apply the same [\x00-\x20\x3b\x7f] validation to every entry in the **kwargs loop (after normalizing the
key case), or remove the deprecated kwargs path; add a regression test for capitalized kwargs.
Credit
Reported as part of an incomplete-patch measurement study (responsible disclosure).
Affected software
Click a technology to see all vulnerabilities affecting it.
| Platform | Package | Vulnerable versions | Fixed in |
|---|---|---|---|
| Python (PyPI) | tornado | >= 6.5.5, < 6.5.8 | 6.5.8 |
References
- https://github.com/tornadoweb/tornado/security/advisories/GHSA-wwv5-g3v4-889x
- https://github.com/tornadoweb/tornado/pull/3704
- https://github.com/tornadoweb/tornado/pull/3706
- https://github.com/tornadoweb/tornado/commit/6ef836e43e1278530041376adb32504daa977b91
- https://github.com/tornadoweb/tornado/commit/da284767eae8e1f0484f123b8c3225f6465b09c7
- https://github.com/tornadoweb/tornado
- https://github.com/tornadoweb/tornado/releases/tag/v6.5.8
- CVSS vector
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N- Weakness (CWE)
CWE-74- Platform
- Python (PyPI)
- Package
tornado- Disclosed
- 01.09.2026
- Updated
- 11.10.2026 15:18
Sources and licenses
OSV / GitHub Advisory Database - GHSA-wwv5-g3v4-889x - CC BY 4.0
Vulnerability history: tornado
All published vulnerabilities of this package (Python (PyPI)), newest first. Shows whether this is a one-off slip or a package that needs watching.
- Total entries
- 23
- First → latest
- 05.2012 09.2026
- Without a fix
- 0
- Exploited in attacks
- 0
Severity breakdown
- High 13
- Medium 8
- Low 2
Disclosures per year
- 2017: 0
- 2018: 0
- 2019: 0
- 2020: 1
- 2021: 0
- 2022: 0
- 2023: 2
- 2024: 3
- 2025: 4
- 2026: 12
earlier: 1
-
Tornado: Incomplete fix for CVE-2026-35536: cookie attribute injection re-opened via the legacy case-insensitive `**kwargs` path in `set_cookie` this entry
Know which vulnerabilities affect your application
With the DockRay integration and software inventory enabled, DockRay checks reported component versions against known vulnerabilities and notifies you about confirmed matches. Coverage depends on the supported technology and available advisory data.