GHSA-wwv5-g3v4-889x
Tornado: Incomplete fix for CVE-2026-35536: cookie attribute injection re-opened via the legacy case-insensitive `**kwargs` path in `set_cookie`
Quick fix
GHSA-wwv5-g3v4-889x — tornado: upgrade to the fixed version with the command below.
pip install --upgrade 'tornado>=6.5.8'Details
## 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.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 trailing `if kwargs:` loop does `morsel[k] = v` with 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).
Are you affected?
Enter the version of the package you're using.
Affected packages
References
- https://github.com/tornadoweb/tornado/security/advisories/GHSA-wwv5-g3v4-889x[WEB]
- https://github.com/tornadoweb/tornado/pull/3704[WEB]
- https://github.com/tornadoweb/tornado/pull/3706[WEB]
- https://github.com/tornadoweb/tornado/commit/6ef836e43e1278530041376adb32504daa977b91[WEB]
- https://github.com/tornadoweb/tornado/commit/da284767eae8e1f0484f123b8c3225f6465b09c7[WEB]
- https://github.com/tornadoweb/tornado[PACKAGE]
- https://github.com/tornadoweb/tornado/releases/tag/v6.5.8[WEB]