Files
poky/meta/recipes-devtools/python/python3/CVE-2026-6019_p2.patch
Sudhir Dumbhare 7731db5592 python3: Fix CVE-2026-6019
This patch applies the upstream fix [1] and follow-up fix [2], as
referenced in [3] and [4], to address an http.cookies.Morsel.js_output()
flaw where inline JavaScript output escaped quotes but did not neutralize
the HTML parser-sensitive </script> sequence.

[1] 3c59b8b53f
[2] e7d4c3ff42
[3] https://github.com/python/cpython/issues/149144
[4] https://security-tracker.debian.org/tracker/CVE-2026-6019

Reference:
https://nvd.nist.gov/vuln/detail/CVE-2026-6019

(From OE-Core rev: e17af14ae72e21f7f63407ba5c88da160c73bea9)

Signed-off-by: Sudhir Dumbhare <sudumbha@cisco.com>
Signed-off-by: Yoann Congal <yoann.congal@smile.fr>
Signed-off-by: Paul Barker <paul@pbarker.dev>
2026-06-26 16:55:53 +01:00

130 lines
5.5 KiB
Diff

From de449bbc6ff4ce869c17fb551dacc69de25d73a9 Mon Sep 17 00:00:00 2001
From: Stan Ulbrych <stan@python.org>
Date: Mon, 8 Jun 2026 20:15:21 +0100
Subject: [PATCH] [3.13] gh-149144: Use `decodeURIComponent()` for UTF-8
support in `js_output()` (GH-149157) (#150949)
CVE: CVE-2026-6019
Upstream-Status: Backport [https://github.com/python/cpython/commit/e7d4c3ff421916986223690a8425d2383f6f3802]
Co-authored-by: Seth Larson <seth@python.org>
(cherry picked from commit e7d4c3ff421916986223690a8425d2383f6f3802)
Signed-off-by: Sudhir Dumbhare <sudumbha@cisco.com>
---
Lib/http/cookies.py | 6 +++---
Lib/test/test_http_cookies.py | 27 ++++++++++++++-------------
2 files changed, 17 insertions(+), 16 deletions(-)
diff --git a/Lib/http/cookies.py b/Lib/http/cookies.py
index aebc2a163e4..2cffa2a9ad6 100644
--- a/Lib/http/cookies.py
+++ b/Lib/http/cookies.py
@@ -389,18 +389,18 @@ class Morsel(dict):
return '<%s: %s>' % (self.__class__.__name__, self.OutputString())
def js_output(self, attrs=None):
- import base64
+ import urllib.parse
# Print javascript
output_string = self.OutputString(attrs)
if _has_control_character(output_string):
raise CookieError("Control characters are not allowed in cookies")
# Base64-encode value to avoid template
# injection in cookie values.
- output_encoded = base64.b64encode(output_string.encode('utf-8')).decode("ascii")
+ output_encoded = urllib.parse.quote(output_string, safe='', encoding='utf-8')
return """
<script type="text/javascript">
<!-- begin hiding
- document.cookie = atob(\"%s\");
+ document.cookie = decodeURIComponent(\"%s\");
// end hiding -->
</script>
""" % (output_encoded,)
diff --git a/Lib/test/test_http_cookies.py b/Lib/test/test_http_cookies.py
index 6aa5df068f9..b9cc59cd1db 100644
--- a/Lib/test/test_http_cookies.py
+++ b/Lib/test/test_http_cookies.py
@@ -1,10 +1,10 @@
# Simple test suite for http/cookies.py
-import base64
import copy
import unittest
import doctest
from http import cookies
import pickle
+import urllib.parse
from test import support
@@ -152,19 +152,19 @@ class CookieTests(unittest.TestCase):
self.assertEqual(C.output(['path']),
'Set-Cookie: Customer="WILE_E_COYOTE"; Path=/acme')
- cookie_encoded = base64.b64encode(b'Customer="WILE_E_COYOTE"; Path=/acme; Version=1').decode('ascii')
+ cookie_encoded = urllib.parse.quote('Customer="WILE_E_COYOTE"; Path=/acme; Version=1', safe='', encoding='utf-8')
self.assertEqual(C.js_output(), fr"""
<script type="text/javascript">
<!-- begin hiding
- document.cookie = atob("{cookie_encoded}");
+ document.cookie = decodeURIComponent("{cookie_encoded}");
// end hiding -->
</script>
""")
- cookie_encoded = base64.b64encode(b'Customer="WILE_E_COYOTE"; Path=/acme').decode('ascii')
+ cookie_encoded = urllib.parse.quote('Customer="WILE_E_COYOTE"; Path=/acme', safe='', encoding='utf-8')
self.assertEqual(C.js_output(['path']), fr"""
<script type="text/javascript">
<!-- begin hiding
- document.cookie = atob("{cookie_encoded}");
+ document.cookie = decodeURIComponent("{cookie_encoded}");
// end hiding -->
</script>
""")
@@ -261,19 +261,19 @@ class CookieTests(unittest.TestCase):
self.assertEqual(C.output(['path']),
'Set-Cookie: Customer="WILE_E_COYOTE"; Path=/acme')
- expected_encoded_cookie = base64.b64encode(b'Customer=\"WILE_E_COYOTE\"; Path=/acme; Version=1').decode('ascii')
+ expected_encoded_cookie = urllib.parse.quote('Customer=\"WILE_E_COYOTE\"; Path=/acme; Version=1', safe='', encoding='utf-8')
self.assertEqual(C.js_output(), fr"""
<script type="text/javascript">
<!-- begin hiding
- document.cookie = atob("{expected_encoded_cookie}");
+ document.cookie = decodeURIComponent("{expected_encoded_cookie}");
// end hiding -->
</script>
""")
- expected_encoded_cookie = base64.b64encode(b'Customer=\"WILE_E_COYOTE\"; Path=/acme').decode('ascii')
+ expected_encoded_cookie = urllib.parse.quote('Customer=\"WILE_E_COYOTE\"; Path=/acme', safe='', encoding='utf-8')
self.assertEqual(C.js_output(['path']), fr"""
<script type="text/javascript">
<!-- begin hiding
- document.cookie = atob("{expected_encoded_cookie}");
+ document.cookie = decodeURIComponent("{expected_encoded_cookie}");
// end hiding -->
</script>
""")
@@ -364,13 +364,14 @@ class MorselTests(unittest.TestCase):
self.assertEqual(
M.output(),
"Set-Cookie: %s=%s; Path=/foo" % (i, "%s_coded_val" % i))
- expected_encoded_cookie = base64.b64encode(
- ("%s=%s; Path=/foo" % (i, "%s_coded_val" % i)).encode("ascii")
- ).decode('ascii')
+ expected_encoded_cookie = urllib.parse.quote(
+ "%s=%s; Path=/foo" % (i, "%s_coded_val" % i),
+ safe='', encoding='utf-8',
+ )
expected_js_output = """
<script type="text/javascript">
<!-- begin hiding
- document.cookie = atob("%s");
+ document.cookie = decodeURIComponent("%s");
// end hiding -->
</script>
""" % (expected_encoded_cookie,)
--
2.35.6