From 87d0887c4fde85232894f84ca0f7f06947b73693 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych Date: Fri, 6 Mar 2026 08:00:24 +0000 Subject: [PATCH 1/3] Patch --- Lib/http/cookies.py | 8 ++++++++ Lib/test/test_http_cookies.py | 30 ++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/Lib/http/cookies.py b/Lib/http/cookies.py index 917280037d4dbb..aefa8f9668b5c4 100644 --- a/Lib/http/cookies.py +++ b/Lib/http/cookies.py @@ -337,9 +337,15 @@ def update(self, values): key = key.lower() if key not in self._reserved: raise CookieError("Invalid attribute %r" % (key,)) + if _has_control_character(key, val): + raise CookieError("Control characters are not allowed in cookies %r %r" % (key, val)) data[key] = val dict.update(self, data) + def __ior__(self, values): + self.update(values) + return self + def isReservedKey(self, K): return K.lower() in self._reserved @@ -524,6 +530,8 @@ def js_output(self, attrs=None): result = [] items = sorted(self.items()) for key, value in items: + if _has_control_character(value.OutputString(attrs)): + raise CookieError("Control characters are not allowed in cookies") result.append(value.js_output(attrs)) return _nulljoin(result) diff --git a/Lib/test/test_http_cookies.py b/Lib/test/test_http_cookies.py index 7d072d5fd67ca7..6e28fdfec93345 100644 --- a/Lib/test/test_http_cookies.py +++ b/Lib/test/test_http_cookies.py @@ -618,6 +618,18 @@ def test_control_characters(self): with self.assertRaises(cookies.CookieError): morsel.set("path", "val", c0) + # .update() + with self.assertRaises(cookies.CookieError): + morsel.update({"path": c0}) + with self.assertRaises(cookies.CookieError): + morsel.update({c0: "val"}) + + # .__ior__() + with self.assertRaises(cookies.CookieError): + morsel |= {"path": c0} + with self.assertRaises(cookies.CookieError): + morsel |= {c0: "val"} + def test_control_characters_output(self): # Tests that even if the internals of Morsel are modified # that a call to .output() has control character safeguards. @@ -638,6 +650,24 @@ def test_control_characters_output(self): with self.assertRaises(cookies.CookieError): cookie.output() + # Tests that .js_output() also has control character safeguards. + for c0 in support.control_characters_c0(): + morsel = cookies.Morsel() + morsel.set("key", "value", "coded-value") + morsel._key = c0 # Override private variable. + cookie = cookies.SimpleCookie() + cookie["cookie"] = morsel + with self.assertRaises(cookies.CookieError): + cookie.js_output() + + morsel = cookies.Morsel() + morsel.set("key", "value", "coded-value") + morsel._coded_value = c0 # Override private variable. + cookie = cookies.SimpleCookie() + cookie["cookie"] = morsel + with self.assertRaises(cookies.CookieError): + cookie.js_output() + def load_tests(loader, tests, pattern): tests.addTest(doctest.DocTestSuite(cookies)) From 63a3b5936a0953c9a7a6a44d29d5b90e1be4e76a Mon Sep 17 00:00:00 2001 From: Stan Ulbrych Date: Fri, 6 Mar 2026 17:03:45 +0000 Subject: [PATCH 2/3] Blurb --- .../next/Security/2026-03-06-17-03-38.gh-issue-145599.kchwZV.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Security/2026-03-06-17-03-38.gh-issue-145599.kchwZV.rst diff --git a/Misc/NEWS.d/next/Security/2026-03-06-17-03-38.gh-issue-145599.kchwZV.rst b/Misc/NEWS.d/next/Security/2026-03-06-17-03-38.gh-issue-145599.kchwZV.rst new file mode 100644 index 00000000000000..788c3e4ac2ebf7 --- /dev/null +++ b/Misc/NEWS.d/next/Security/2026-03-06-17-03-38.gh-issue-145599.kchwZV.rst @@ -0,0 +1 @@ +Reject control characters in :class:`http.cookies.Morsel` fields and values. From dce754d2f82d22bdf6d10d600e0fd05e8f763f32 Mon Sep 17 00:00:00 2001 From: Stan Ulbrych Date: Fri, 6 Mar 2026 17:46:39 +0000 Subject: [PATCH 3/3] Seth's review, fix blurb --- .../Security/2026-03-06-17-03-38.gh-issue-145599.kchwZV.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Security/2026-03-06-17-03-38.gh-issue-145599.kchwZV.rst b/Misc/NEWS.d/next/Security/2026-03-06-17-03-38.gh-issue-145599.kchwZV.rst index 788c3e4ac2ebf7..f820ef6c5d1ed3 100644 --- a/Misc/NEWS.d/next/Security/2026-03-06-17-03-38.gh-issue-145599.kchwZV.rst +++ b/Misc/NEWS.d/next/Security/2026-03-06-17-03-38.gh-issue-145599.kchwZV.rst @@ -1 +1,3 @@ -Reject control characters in :class:`http.cookies.Morsel` fields and values. +Reject control characters in :class:`http.cookies.Morsel` +:meth:`~http.cookies.Morsel.update` and +:meth:`~http.cookies.BaseCookie.js_output`.