GHSA-wwv5-g3v4-889x: Pip/tornado vulnerability
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.
python self.setcookie("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.setcookie("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.setcookie: the validation loop covers only the lowercase named args; the trailing if kwargs: loop does morsel[k] = v with no character validation.
Steps to reproduce GET /upper (uses Domain= kwarg) emits Set-Cookie: cupper=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
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
pip/tornadoto a version that resolves this vulnerability.Fixed in 6.5.8 - Upgrade
Upgrade to a fixed release to a version that resolves this vulnerability.
Patch CVE-2026-35536 - Configuration
Extend the CVE-2026-35536 validation loop so it applies the same [\x00-\x20\x3b\x7f] character rejection to every `**kwargs` cookie attribute value, not only the lowercase named args (Domain/path/Name/etc.). Ensure normalization/case handling is applied before validating and assigning into `Morsel`.
tornado/web.py (RequestHandler.set_cookie) Set-Cookie attribute validation for deprecated **kwargs = Reject characters in [\x00-\x20\x3b\x7f] for every entry in the **kwargs loop (after normalizing key case) - Configuration
Remove the still-live deprecated `**kwargs` code path in `RequestHandler.set_cookie` that reaches `morsel[k] = v` without validation, or disable it so only the explicitly validated lowercase parameters (e.g., `name`, `domain`, `path`, `samesite`) are accepted.
tornado/web.py (RequestHandler.set_cookie) deprecated **kwargs cookie argument handling = Remove/disable the deprecated **kwargs path - Configuration
Augment the existing `SetCookieForbiddenCharHandler` regression test to exercise the bypass case: capitalized/legacy kwarg names that map case-insensitively (e.g., `Domain=
tornado/web.py tests (SetCookieForbiddenCharHandler) regression test coverage for capitalized cookie kwarg names = Add test cases for capitalized/legacy kwarg names (e.g., Domain=, Path=, SameSite=, Max-Age=)
Event History
Frequently Asked Questions
Which applications are realistically exposed to this issue?
Applications are exposed when they pass attacker-controlled cookie attribute values through the deprecated **kwargs path to RequestHandler.set_cookie, particularly using capitalized reserved keys such as Domain, Path, SameSite, or Max-Age. The lowercase named arguments name, domain, path, and samesite are covered by the validation loop.
What does an attacker need to exploit it?
An attacker needs control over a value assigned through the unvalidated **kwargs cookie-attribute path. Supplying a semicolon in a capitalized attribute value can inject additional Set-Cookie attributes, such as Secure or SameSite=None.
What can be done before a patch is available?
Avoid passing untrusted values through **kwargs to set_cookie. Use the lowercase named parameters where applicable, since the described validation rejects semicolons and the other listed forbidden characters for those parameters.
How can I identify potentially affected code?
Review RequestHandler.set_cookie calls for use of **kwargs or capitalized cookie attribute keys, including Domain, Path, SameSite, and Max-Age. Prioritize cases where those values can be influenced by a request, user input, or another untrusted source.