[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#1104401: bookworm-pu: package python3.11/3.11.2-6+deb12u6



Package: release.debian.org
Severity: normal
Tags: bookworm
User: release.debian.org@packages.debian.org
Usertags: pu
X-Debbugs-Cc: security@debian.org, Matthias Klose <doko@debian.org>

  * CVE-2025-0938: urlparse accepted hostname containing [ or ]
  * CVE-2025-1795: Don't encode list separators in email headers
diffstat for python3.11-3.11.2 python3.11-3.11.2

 changelog                                                               |    8 
 patches/0001-3.11-gh-105704-Disallow-square-brackets-and-in-domai.patch |  112 ++++++++++
 patches/0002-3.11-gh-100884-email-_header_value_parser-don-t-enco.patch |   60 +++++
 patches/0003-3.11-gh-118643-Fix-AttributeError-in-the-email-modul.patch |   82 +++++++
 patches/series                                                          |    3 
 5 files changed, 265 insertions(+)

diff -Nru python3.11-3.11.2/debian/changelog python3.11-3.11.2/debian/changelog
--- python3.11-3.11.2/debian/changelog	2024-11-30 23:22:50.000000000 +0200
+++ python3.11-3.11.2/debian/changelog	2025-04-28 17:11:48.000000000 +0300
@@ -1,3 +1,11 @@
+python3.11 (3.11.2-6+deb12u6) bookworm; urgency=medium
+
+  * Non-maintainer upload.
+  * CVE-2025-0938: urlparse accepted hostname containing [ or ]
+  * CVE-2025-1795: Don't encode list separators in email headers
+
+ -- Adrian Bunk <bunk@debian.org>  Mon, 28 Apr 2025 17:11:48 +0300
+
 python3.11 (3.11.2-6+deb12u5) bookworm; urgency=medium
 
   * Non-maintainer upload.
diff -Nru python3.11-3.11.2/debian/patches/0001-3.11-gh-105704-Disallow-square-brackets-and-in-domai.patch python3.11-3.11.2/debian/patches/0001-3.11-gh-105704-Disallow-square-brackets-and-in-domai.patch
--- python3.11-3.11.2/debian/patches/0001-3.11-gh-105704-Disallow-square-brackets-and-in-domai.patch	1970-01-01 02:00:00.000000000 +0200
+++ python3.11-3.11.2/debian/patches/0001-3.11-gh-105704-Disallow-square-brackets-and-in-domai.patch	2025-04-28 17:11:48.000000000 +0300
@@ -0,0 +1,112 @@
+From 4f13593827072325d77a9a880458b205ab980ad0 Mon Sep 17 00:00:00 2001
+From: "Miss Islington (bot)"
+ <31488909+miss-islington@users.noreply.github.com>
+Date: Wed, 19 Feb 2025 14:13:52 +0100
+Subject: [3.11] gh-105704: Disallow square brackets (`[` and `]`) in domain
+ names for parsed URLs (GH-129418) (#129528)
+
+Co-authored-by: Seth Michael Larson <seth@python.org>
+Co-authored-by: Peter Bierma <zintensitydev@gmail.com>
+---
+ Lib/test/test_urlparse.py | 37 ++++++++++++++++++++++++++++++++++++-
+ Lib/urllib/parse.py       | 20 ++++++++++++++++++--
+ 2 files changed, 54 insertions(+), 3 deletions(-)
+
+diff --git a/Lib/test/test_urlparse.py b/Lib/test/test_urlparse.py
+index 83ea618291e..45cca11da47 100644
+--- a/Lib/test/test_urlparse.py
++++ b/Lib/test/test_urlparse.py
+@@ -1103,16 +1103,51 @@ def test_invalid_bracketed_hosts(self):
+         self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@[0439:23af::2309::fae7:1234]/Path?Query')
+         self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@[0439:23af:2309::fae7:1234:2342:438e:192.0.2.146]/Path?Query')
+         self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@]v6a.ip[/Path')
++        self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[v6a.ip]')
++        self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[v6a.ip].suffix')
++        self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[v6a.ip]/')
++        self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[v6a.ip].suffix/')
++        self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[v6a.ip]?')
++        self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[v6a.ip].suffix?')
++        self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]')
++        self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[::1].suffix')
++        self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]/')
++        self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[::1].suffix/')
++        self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]?')
++        self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[::1].suffix?')
++        self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]:a')
++        self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[::1].suffix:a')
++        self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]:a1')
++        self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[::1].suffix:a1')
++        self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]:1a')
++        self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[::1].suffix:1a')
++        self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]:')
++        self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[::1].suffix:/')
++        self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[::1]:?')
++        self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://user@prefix.[v6a.ip]')
++        self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://user@[v6a.ip].suffix')
++        self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://[v6a.ip')
++        self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://v6a.ip]')
++        self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://]v6a.ip[')
++        self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://]v6a.ip')
++        self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://v6a.ip[')
++        self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix.[v6a.ip')
++        self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://v6a.ip].suffix')
++        self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix]v6a.ip[suffix')
++        self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix]v6a.ip')
++        self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://v6a.ip[suffix')
+ 
+     def test_splitting_bracketed_hosts(self):
+-        p1 = urllib.parse.urlsplit('scheme://user@[v6a.ip]/path?query')
++        p1 = urllib.parse.urlsplit('scheme://user@[v6a.ip]:1234/path?query')
+         self.assertEqual(p1.hostname, 'v6a.ip')
+         self.assertEqual(p1.username, 'user')
+         self.assertEqual(p1.path, '/path')
++        self.assertEqual(p1.port, 1234)
+         p2 = urllib.parse.urlsplit('scheme://user@[0439:23af:2309::fae7%test]/path?query')
+         self.assertEqual(p2.hostname, '0439:23af:2309::fae7%test')
+         self.assertEqual(p2.username, 'user')
+         self.assertEqual(p2.path, '/path')
++        self.assertIs(p2.port, None)
+         p3 = urllib.parse.urlsplit('scheme://user@[0439:23af:2309::fae7:1234:192.0.2.146%test]/path?query')
+         self.assertEqual(p3.hostname, '0439:23af:2309::fae7:1234:192.0.2.146%test')
+         self.assertEqual(p3.username, 'user')
+diff --git a/Lib/urllib/parse.py b/Lib/urllib/parse.py
+index e5f0b784bf6..5233020a9f0 100644
+--- a/Lib/urllib/parse.py
++++ b/Lib/urllib/parse.py
+@@ -436,6 +436,23 @@ def _checknetloc(netloc):
+             raise ValueError("netloc '" + netloc + "' contains invalid " +
+                              "characters under NFKC normalization")
+ 
++def _check_bracketed_netloc(netloc):
++    # Note that this function must mirror the splitting
++    # done in NetlocResultMixins._hostinfo().
++    hostname_and_port = netloc.rpartition('@')[2]
++    before_bracket, have_open_br, bracketed = hostname_and_port.partition('[')
++    if have_open_br:
++        # No data is allowed before a bracket.
++        if before_bracket:
++            raise ValueError("Invalid IPv6 URL")
++        hostname, _, port = bracketed.partition(']')
++        # No data is allowed after the bracket but before the port delimiter.
++        if port and not port.startswith(":"):
++            raise ValueError("Invalid IPv6 URL")
++    else:
++        hostname, _, port = hostname_and_port.partition(':')
++    _check_bracketed_host(hostname)
++
+ # Valid bracketed hosts are defined in
+ # https://www.rfc-editor.org/rfc/rfc3986#page-49 and https://url.spec.whatwg.org/
+ def _check_bracketed_host(hostname):
+@@ -496,8 +513,7 @@ def urlsplit(url, scheme='', allow_fragments=True):
+                 (']' in netloc and '[' not in netloc)):
+             raise ValueError("Invalid IPv6 URL")
+         if '[' in netloc and ']' in netloc:
+-            bracketed_host = netloc.partition('[')[2].partition(']')[0]
+-            _check_bracketed_host(bracketed_host)
++            _check_bracketed_netloc(netloc)
+     if allow_fragments and '#' in url:
+         url, fragment = url.split('#', 1)
+     if '?' in url:
+-- 
+2.30.2
+
diff -Nru python3.11-3.11.2/debian/patches/0002-3.11-gh-100884-email-_header_value_parser-don-t-enco.patch python3.11-3.11.2/debian/patches/0002-3.11-gh-100884-email-_header_value_parser-don-t-enco.patch
--- python3.11-3.11.2/debian/patches/0002-3.11-gh-100884-email-_header_value_parser-don-t-enco.patch	1970-01-01 02:00:00.000000000 +0200
+++ python3.11-3.11.2/debian/patches/0002-3.11-gh-100884-email-_header_value_parser-don-t-enco.patch	2025-04-28 17:11:21.000000000 +0300
@@ -0,0 +1,60 @@
+From b85561b1141471dcef77fc0f76d03736f9da8b92 Mon Sep 17 00:00:00 2001
+From: "Miss Islington (bot)"
+ <31488909+miss-islington@users.noreply.github.com>
+Date: Sat, 17 Feb 2024 14:01:02 +0100
+Subject: [3.11] gh-100884: email/_header_value_parser: don't encode list
+ separators (GH-100885) (GH-115593)
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+ListSeparator should not be encoded. This could happen when a long line
+pushes its separator to the next line, which would have been encoded.
+(cherry picked from commit 09fab93c3d857496c0bd162797fab816c311ee48)
+
+Co-authored-by: Thomas Weißschuh <thomas@t-8ch.de>
+---
+ Lib/email/_header_value_parser.py                | 3 ++-
+ Lib/test/test_email/test__header_value_parser.py | 5 +++++
+ 2 files changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/Lib/email/_header_value_parser.py b/Lib/email/_header_value_parser.py
+index e1b99d5b417..87c4ae9f167 100644
+--- a/Lib/email/_header_value_parser.py
++++ b/Lib/email/_header_value_parser.py
+@@ -951,6 +951,7 @@ class _InvalidEwError(errors.HeaderParseError):
+ # up other parse trees.  Maybe should have  tests for that, too.
+ DOT = ValueTerminal('.', 'dot')
+ ListSeparator = ValueTerminal(',', 'list-separator')
++ListSeparator.as_ew_allowed = False
+ RouteComponentMarker = ValueTerminal('@', 'route-component-marker')
+ 
+ #
+@@ -2024,7 +2025,7 @@ def get_address_list(value):
+             address_list.defects.append(errors.InvalidHeaderDefect(
+                 "invalid address in address-list"))
+         if value:  # Must be a , at this point.
+-            address_list.append(ValueTerminal(',', 'list-separator'))
++            address_list.append(ListSeparator)
+             value = value[1:]
+     return address_list, value
+ 
+diff --git a/Lib/test/test_email/test__header_value_parser.py b/Lib/test/test_email/test__header_value_parser.py
+index 854f2ff009c..7063ce7d71c 100644
+--- a/Lib/test/test_email/test__header_value_parser.py
++++ b/Lib/test/test_email/test__header_value_parser.py
+@@ -2946,6 +2946,11 @@ def test_address_list_with_unicode_names_in_quotes(self):
+             '=?utf-8?q?H=C3=BCbsch?= Kaktus <beautiful@example.com>,\n'
+                 ' =?utf-8?q?bei=C3=9Ft_bei=C3=9Ft?= <biter@example.com>\n')
+ 
++    def test_address_list_with_list_separator_after_fold(self):
++        to = '0123456789' * 8 + '@foo, ä <foo@bar>'
++        self._test(parser.get_address_list(to)[0],
++                   '0123456789' * 8 + '@foo,\n =?utf-8?q?=C3=A4?= <foo@bar>\n')
++
+     # XXX Need tests with comments on various sides of a unicode token,
+     # and with unicode tokens in the comments.  Spaces inside the quotes
+     # currently don't do the right thing.
+-- 
+2.30.2
+
diff -Nru python3.11-3.11.2/debian/patches/0003-3.11-gh-118643-Fix-AttributeError-in-the-email-modul.patch python3.11-3.11.2/debian/patches/0003-3.11-gh-118643-Fix-AttributeError-in-the-email-modul.patch
--- python3.11-3.11.2/debian/patches/0003-3.11-gh-118643-Fix-AttributeError-in-the-email-modul.patch	1970-01-01 02:00:00.000000000 +0200
+++ python3.11-3.11.2/debian/patches/0003-3.11-gh-118643-Fix-AttributeError-in-the-email-modul.patch	2025-04-28 17:11:21.000000000 +0300
@@ -0,0 +1,82 @@
+From c9b1142da7f477f84c7d7b9324cc4883cb8a9be4 Mon Sep 17 00:00:00 2001
+From: Serhiy Storchaka <storchaka@gmail.com>
+Date: Thu, 23 May 2024 15:09:03 +0300
+Subject: [3.11] gh-118643: Fix AttributeError in the email module (GH-119099)
+ (#119393)
+
+Fix regression introduced in gh-100884: AttributeError when re-fold a long
+address list.
+
+Also fix more cases of incorrect encoding of the address separator in the
+address list missed in gh-100884.
+(cherry picked from commit 858b9e85fcdd495947c9e892ce6e3734652c48f2)
+---
+ Lib/email/_header_value_parser.py                | 16 +++++++++++++---
+ Lib/test/test_email/test__header_value_parser.py | 12 ++++++++++--
+ 2 files changed, 23 insertions(+), 5 deletions(-)
+
+diff --git a/Lib/email/_header_value_parser.py b/Lib/email/_header_value_parser.py
+index 87c4ae9f167..04dbfa2ee86 100644
+--- a/Lib/email/_header_value_parser.py
++++ b/Lib/email/_header_value_parser.py
+@@ -952,6 +952,7 @@ class _InvalidEwError(errors.HeaderParseError):
+ DOT = ValueTerminal('.', 'dot')
+ ListSeparator = ValueTerminal(',', 'list-separator')
+ ListSeparator.as_ew_allowed = False
++ListSeparator.syntactic_break = False
+ RouteComponentMarker = ValueTerminal('@', 'route-component-marker')
+ 
+ #
+@@ -2826,13 +2827,22 @@ def _refold_parse_tree(parse_tree, *, policy):
+             if not hasattr(part, 'encode'):
+                 # It's not a Terminal, do each piece individually.
+                 parts = list(part) + parts
+-            else:
++                want_encoding = False
++                continue
++            elif part.as_ew_allowed:
+                 # It's a terminal, wrap it as an encoded word, possibly
+                 # combining it with previously encoded words if allowed.
+                 last_ew = _fold_as_ew(tstr, lines, maxlen, last_ew,
+                                       part.ew_combine_allowed, charset)
+-            want_encoding = False
+-            continue
++                want_encoding = False
++                continue
++            else:
++                # It's a terminal which should be kept non-encoded
++                # (e.g. a ListSeparator).
++                last_ew = None
++                want_encoding = False
++                # fall through
++
+         if len(tstr) <= maxlen - len(lines[-1]):
+             lines[-1] += tstr
+             continue
+diff --git a/Lib/test/test_email/test__header_value_parser.py b/Lib/test/test_email/test__header_value_parser.py
+index 7063ce7d71c..1f575545a11 100644
+--- a/Lib/test/test_email/test__header_value_parser.py
++++ b/Lib/test/test_email/test__header_value_parser.py
+@@ -2947,9 +2947,17 @@ def test_address_list_with_unicode_names_in_quotes(self):
+                 ' =?utf-8?q?bei=C3=9Ft_bei=C3=9Ft?= <biter@example.com>\n')
+ 
+     def test_address_list_with_list_separator_after_fold(self):
+-        to = '0123456789' * 8 + '@foo, ä <foo@bar>'
++        a = 'x' * 66 + '@example.com'
++        to = f'{a}, "Hübsch Kaktus" <beautiful@example.com>'
+         self._test(parser.get_address_list(to)[0],
+-                   '0123456789' * 8 + '@foo,\n =?utf-8?q?=C3=A4?= <foo@bar>\n')
++            f'{a},\n =?utf-8?q?H=C3=BCbsch?= Kaktus <beautiful@example.com>\n')
++
++        a = '.' * 79
++        to = f'"{a}" <xyz@example.com>, "Hübsch Kaktus" <beautiful@example.com>'
++        self._test(parser.get_address_list(to)[0],
++            f'{a}\n'
++            ' <xyz@example.com>, =?utf-8?q?H=C3=BCbsch?= Kaktus '
++            '<beautiful@example.com>\n')
+ 
+     # XXX Need tests with comments on various sides of a unicode token,
+     # and with unicode tokens in the comments.  Spaces inside the quotes
+-- 
+2.30.2
+
diff -Nru python3.11-3.11.2/debian/patches/series python3.11-3.11.2/debian/patches/series
--- python3.11-3.11.2/debian/patches/series	2024-11-30 23:22:50.000000000 +0200
+++ python3.11-3.11.2/debian/patches/series	2025-04-28 17:11:48.000000000 +0300
@@ -58,3 +58,6 @@
 0003-3.11-gh-123067-Fix-quadratic-complexity-in-parsing-q.patch
 0004-3.11-gh-124651-Quote-template-strings-in-venv-activa.patch
 0005-3.11-gh-103848-Adds-checks-to-ensure-that-bracketed-.patch
+0001-3.11-gh-105704-Disallow-square-brackets-and-in-domai.patch
+0002-3.11-gh-100884-email-_header_value_parser-don-t-enco.patch
+0003-3.11-gh-118643-Fix-AttributeError-in-the-email-modul.patch

Reply to: