Tornado: Incomplete fix for CVE-2026-35536: cookie attribute injection re-opened via the…
Key facts
- Attack vector
- —
- Privileges required
- —
- User interaction
- —
- Attack complexity
- —
- Impact type
- —
- Confidentiality · integrity · availability
- —
- Fix status
- Fixed
No CVSS vector from any source. Fix status from GitHub.
Summary
## 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).
Why it matters now
SSVC decision points
Not available: CISA has not published SSVC decision points for this record.
Affected products
| Vendor | Product | Affected versions | Fixed in | Status | Source |
|---|---|---|---|---|---|
| — | tornado (PyPI) | 6.5.5 to before 6.5.8 | 6.5.8 | Patch available | GHSA-wwv5-g3v4-889x |
- tornado (PyPI) Vendor— Affected 6.5.5 to before 6.5.8 Fixed in 6.5.8 Patch available GHSA-wwv5-g3v4-889x
Remediation
- Fix · GHSA-wwv5-g3v4-889x tornado (PyPI) Fixed in 6.5.8 Advisory →
Timeline
- 2026-10-03 Threatist record created from GHSA-wwv5-g3v4-889x
References
Other 7
- 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
Sources
This product uses the NVD API but is not endorsed or certified by the NVD. Sources and licences