GCVE Workshop - 22 September 2026 (14:00-18:00), Luxembourg Before The Vulnopticon Conference - Registration

BREW-SICKCHILL-GHSA-WWV5… (GHSA-WWV5-G3V4-889X)

Vulnerability from osv_homebrew – Published: 2026-09-02 09:54 – Updated: 2026-09-17 18:24 – Source website
VLAI
Summary
Tornado: Incomplete fix for CVE-2026-35536: cookie attribute injection re-opened via the legacy case-insensitive `**kwargs` path in `set_cookie`
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.

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.pyRequestHandler.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).


{
  "affected": [
    {
      "ecosystem_specific": {
        "fix": "bump",
        "range_state": "fixed",
        "resource": "tornado",
        "resource_purl": "pkg:pypi/tornado@6.5.8",
        "upstream_fixed_in": "6.5.8"
      },
      "package": {
        "ecosystem": "Homebrew",
        "name": "sickchill",
        "purl": "pkg:brew/sickchill"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "2024.3.1_5"
            },
            {
              "fixed": "2024.3.1_8"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "database_specific": {
    "confidence": "high",
    "source": "matched",
    "strategy": "registry",
    "upstream_evidence": [
      {
        "ecosystem": "PyPI",
        "key": "pkg:pypi/tornado@6.5.8",
        "name": "tornado",
        "resource": "tornado",
        "strategy": "registry",
        "subject_version": "6.5.8"
      }
    ]
  },
  "details": "## Summary\nThe CVE-2026-35536 fix added a validation loop that rejects `[\\x00-\\x20\\x3b\\x7f]`, but only for the\nhardcoded **lowercase** keys `name`/`domain`/`path`/`samesite`. The still-live deprecated `**kwargs` path\nwrites attacker-supplied attribute values straight into the `Morsel` with no validation, and because\n`Morsel.__setitem__` is case-insensitive, a capitalized kwarg (`Domain=`, `Path=`, `SameSite=`, `Max-Age=`)\nroutes to the same reserved attribute while bypassing the loop \u2014 re-opening `;`-delimited attribute injection.\n\n```python\nself.set_cookie(\"sid\", \"abc\", Domain=\"evil.com; Secure; SameSite=None\")\n#  -\u003e Set-Cookie: sid=abc; Domain=evil.com; Secure; SameSite=None; Path=/\n# Sanity (the canonical lowercase named arg IS blocked):\nself.set_cookie(\"sid\", \"abc\", domain=\"evil.com; Secure\")   # -\u003e http.cookies.CookieError\n```\n\nThe patch\u0027s regression test (`SetCookieForbiddenCharHandler`) only exercises the four named params, never the\n`**kwargs` path, so the gap is not regression-covered.\n\n## Affected code\n- `tornado/web.py` \u2192 `RequestHandler.set_cookie`: the validation loop covers only the lowercase named args;\n  the trailing `if kwargs:` loop does `morsel[k] = v` with no character validation.\n\n## Steps to reproduce\n`GET /upper` (uses `Domain=` kwarg) emits `Set-Cookie: c_upper=v; Domain=evil.com; Secure; SameSite=None; Path=/`; `GET /lower` (uses lowercase\n`domain=`) returns a `CookieError`.\n\n## Impact\nInjection of independent cookie attributes (force/drop `Secure`/`HttpOnly`/`SameSite`, rebind `Domain`/`Path`)\n\u2014 the same impact CVE-2026-35536 closed, via the sibling path the patch missed. Conditional on the app using\na capitalized/legacy keyword.\n\n## Suggested remediation\nApply the same `[\\x00-\\x20\\x3b\\x7f]` validation to every entry in the `**kwargs` loop (after normalizing the\nkey case), or remove the deprecated kwargs path; add a regression test for capitalized kwargs.\n\n## Credit\nReported as part of an incomplete-patch measurement study (responsible disclosure).",
  "id": "BREW-sickchill-GHSA-wwv5-g3v4-889x",
  "modified": "2026-09-17T18:24:58Z",
  "published": "2026-09-02T09:54:19Z",
  "references": [
    {
      "type": "WEB",
      "url": "https://github.com/tornadoweb/tornado/security/advisories/GHSA-wwv5-g3v4-889x"
    },
    {
      "type": "WEB",
      "url": "https://github.com/tornadoweb/tornado/pull/3704"
    },
    {
      "type": "WEB",
      "url": "https://github.com/tornadoweb/tornado/pull/3706"
    },
    {
      "type": "WEB",
      "url": "https://github.com/tornadoweb/tornado/commit/6ef836e43e1278530041376adb32504daa977b91"
    },
    {
      "type": "WEB",
      "url": "https://github.com/tornadoweb/tornado/commit/da284767eae8e1f0484f123b8c3225f6465b09c7"
    },
    {
      "type": "PACKAGE",
      "url": "https://github.com/tornadoweb/tornado"
    },
    {
      "type": "WEB",
      "url": "https://github.com/tornadoweb/tornado/releases/tag/v6.5.8"
    }
  ],
  "schema_version": "1.7.3",
  "severity": [
    {
      "score": "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",
      "type": "CVSS_V4"
    }
  ],
  "summary": "Tornado: Incomplete fix for CVE-2026-35536: cookie attribute injection re-opened via the legacy case-insensitive `**kwargs` path in `set_cookie`",
  "upstream": [
    "GHSA-wwv5-g3v4-889x",
    "CVE-2026-91991"
  ]
}



Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Forecast uses a logistic model when the trend is rising, or an exponential decay model when the trend is falling. Fitted via linearized least squares.

Sightings

Author Source Type Date Other

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or observed by the user.
  • Confirmed: The vulnerability has been validated from an analyst's perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
  • Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
  • Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
  • Not confirmed: The user expressed doubt about the validity of the vulnerability.
  • Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.

Loading…

Detection rules are retrieved from Rulezet.

Loading…

Loading…

Related by attack behaviour

Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.


Loading…