Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 122 additions & 0 deletions SPECS/python3/CVE-2025-11468.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
From b2792b2e4e33cbacda5518dfdbb91b4e0ed21c61 Mon Sep 17 00:00:00 2001
From: AllSpark <allspark@microsoft.com>
Date: Tue, 10 Mar 2026 11:38:58 +0000
Subject: [PATCH] gh-143935: Email preserve parens when folding comments
(GH-143936)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Fix a bug in the folding of comments when flattening an email message
using a modern email policy. Comments consisting of a very long sequence of
non-foldable characters could trigger a forced line wrap that omitted the
required leading space on the continuation line, causing the remainder of
the comment to be interpreted as a new header field. This enabled header
injection with carefully crafted inputs.

(cherry picked from commit 17d1490)

Co-authored-by: Seth Michael Larson <seth@python.org>
Co-authored-by: Denis Ledoux <dle@odoo.com>

- Issue: Fix folding of long comments of unfoldable characters in email headers #143935

Signed-off-by: Edgar Ramírez Mondragón <edgarrm358@gmail.com>
Signed-off-by: Azure Linux Security Servicing Account <azurelinux-security@microsoft.com>
Upstream-reference: AI Backport of https://github.com/python/cpython/pull/144350.patch
---
Lib/email/_header_value_parser.py | 27 +++++++++++++++++--
.../test_email/test__header_value_parser.py | 24 +++++++++++++++++
2 files changed, 49 insertions(+), 2 deletions(-)

diff --git a/Lib/email/_header_value_parser.py b/Lib/email/_header_value_parser.py
index 8a0295a..3d071ea 100644
--- a/Lib/email/_header_value_parser.py
+++ b/Lib/email/_header_value_parser.py
@@ -95,8 +95,18 @@ EXTENDED_ATTRIBUTE_ENDS = ATTRIBUTE_ENDS - set('%')
NLSET = {'\n', '\r'}
SPECIALSNL = SPECIALS | NLSET

+def make_quoted_pairs(value):
+ return str(value).replace('\\', '\\\\').replace('"', '\\"')
+
+
+def make_parenthesis_pairs(value):
+ """Escape parenthesis and backslash for use within a comment."""
+ return str(value).replace('\\', '\\\\') \
+ .replace('(', '\\(').replace(')', '\\)'
+
def quote_string(value):
- return '"'+str(value).replace('\\', '\\\\').replace('"', r'\"')+'"'
+ escaped = make_quoted_pairs(value)
+ return f'"{escaped}"'

# Match a RFC 2047 word, looks like =?utf-8?q?someword?=
rfc2047_matcher = re.compile(r'''
@@ -919,7 +929,7 @@ class WhiteSpaceTerminal(Terminal):
return ' '

def startswith_fws(self):
- return True
+ return self and self[0] in WSP


class ValueTerminal(Terminal):
@@ -2849,6 +2859,19 @@ def _refold_parse_tree(parse_tree, *, policy):
if not hasattr(part, 'encode'):
# It's not a terminal, try folding the subparts.
newparts = list(part)
+ if part.token_type == 'quoted-string':
+ newparts = (
+ [ValueTerminal('"', 'ptext')] +
+ [ValueTerminal(make_quoted_pairs(p), 'ptext')
+ for p in newparts] +
+ [ValueTerminal('"', 'ptext')])
+ if part.token_type == 'comment':
+ newparts = (
+ [ValueTerminal('(', 'ptext')] +
+ [ValueTerminal(make_parenthesis_pairs(p), 'ptext')
+ if p.token_type == 'ptext' else p
+ for p in newparts] +
+ [ValueTerminal(')', 'ptext')])
if not part.as_ew_allowed:
wrap_as_ew_blocked += 1
newparts.append(end_ew_not_allowed)
diff --git a/Lib/test/test_email/test__header_value_parser.py b/Lib/test/test_email/test__header_value_parser.py
index 7063ce7..9755267 100644
--- a/Lib/test/test_email/test__header_value_parser.py
+++ b/Lib/test/test_email/test__header_value_parser.py
@@ -2951,6 +2951,30 @@ class TestFolding(TestEmailBase):
self._test(parser.get_address_list(to)[0],
'0123456789' * 8 + '@foo,\n =?utf-8?q?=C3=A4?= <foo@bar>\n')

+
+ def test_address_list_with_long_unwrapable_comment(self):
+ policy = self.policy.clone(max_line_length=40)
+ cases = [
+ # (to, folded)
+ ('(loremipsumdolorsitametconsecteturadipi)<spy@example.org>',
+ '(loremipsumdolorsitametconsecteturadipi)<spy@example.org>\n'),
+ ('<spy@example.org>(loremipsumdolorsitametconsecteturadipi)',
+ '<spy@example.org>(loremipsumdolorsitametconsecteturadipi)\n'),
+ ('(loremipsum dolorsitametconsecteturadipi)<spy@example.org>',
+ '(loremipsum dolorsitametconsecteturadipi)<spy@example.org>\n'),
+ ('<spy@example.org>(loremipsum dolorsitametconsecteturadipi)',
+ '<spy@example.org>(loremipsum\n dolorsitametconsecteturadipi)\n'),
+ ('(Escaped \\( \\) chars \\\\ in comments stay escaped)<spy@example.org>',
+ '(Escaped \\( \\) chars \\\\ in comments stay\n escaped)<spy@example.org>\n'),
+ ('((loremipsum)(loremipsum)(loremipsum)(loremipsum))<spy@example.org>',
+ '((loremipsum)(loremipsum)(loremipsum)(loremipsum))<spy@example.org>\n'),
+ ('((loremipsum)(loremipsum)(loremipsum) (loremipsum))<spy@example.org>',
+ '((loremipsum)(loremipsum)(loremipsum)\n (loremipsum))<spy@example.org>\n'),
+ ]
+ for (to, folded) in cases:
+ with self.subTest(to=to):
+ self._test(parser.get_address_list(to)[0], folded, policy=policy)
+
# 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.45.4

6 changes: 5 additions & 1 deletion SPECS/python3/python3.spec
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
Summary: A high-level scripting language
Name: python3
Version: 3.9.19
Release: 19%{?dist}
Release: 20%{?dist}
License: PSF
Vendor: Microsoft Corporation
Distribution: Mariner
Expand Down Expand Up @@ -54,6 +54,7 @@ Patch1004: CVE-2024-37891.patch
Patch1005: CVE-2025-50181.patch
Patch1006: CVE-2023-5752.patch
Patch1007: CVE-2023-45803.patch
Patch1008: CVE-2025-11468.patch

BuildRequires: bzip2-devel
BuildRequires: expat-devel >= 2.1.0
Expand Down Expand Up @@ -387,6 +388,9 @@ make test TESTOPTS="-x test_multiprocessing_spawn -x test_socket -x test_email"
%{_libdir}/python%{majmin}/test/*

%changelog
* Tue Mar 10 2026 Azure Linux Security Servicing Account <azurelinux-security@microsoft.com> - 3.9.19-20
- Patch for CVE-2025-11468

* Fri Jan 30 2026 Azure Linux Security Servicing Account <azurelinux-security@microsoft.com> - 3.9.19-19
- Patch for CVE-2026-0865, CVE-2025-12084

Expand Down
8 changes: 4 additions & 4 deletions toolkit/resources/manifests/package/pkggen_core_aarch64.txt
Original file line number Diff line number Diff line change
Expand Up @@ -237,10 +237,10 @@ ca-certificates-base-2.0.0-25.cm2.noarch.rpm
ca-certificates-2.0.0-25.cm2.noarch.rpm
dwz-0.14-2.cm2.aarch64.rpm
unzip-6.0-22.cm2.aarch64.rpm
python3-3.9.19-19.cm2.aarch64.rpm
python3-devel-3.9.19-19.cm2.aarch64.rpm
python3-libs-3.9.19-19.cm2.aarch64.rpm
python3-setuptools-3.9.19-19.cm2.noarch.rpm
python3-3.9.19-20.cm2.aarch64.rpm
python3-devel-3.9.19-20.cm2.aarch64.rpm
python3-libs-3.9.19-20.cm2.aarch64.rpm
python3-setuptools-3.9.19-20.cm2.noarch.rpm
python3-pygments-2.4.2-7.cm2.noarch.rpm
which-2.21-8.cm2.aarch64.rpm
libselinux-3.2-1.cm2.aarch64.rpm
Expand Down
8 changes: 4 additions & 4 deletions toolkit/resources/manifests/package/pkggen_core_x86_64.txt
Original file line number Diff line number Diff line change
Expand Up @@ -237,10 +237,10 @@ ca-certificates-base-2.0.0-25.cm2.noarch.rpm
ca-certificates-2.0.0-25.cm2.noarch.rpm
dwz-0.14-2.cm2.x86_64.rpm
unzip-6.0-22.cm2.x86_64.rpm
python3-3.9.19-19.cm2.x86_64.rpm
python3-devel-3.9.19-19.cm2.x86_64.rpm
python3-libs-3.9.19-19.cm2.x86_64.rpm
python3-setuptools-3.9.19-19.cm2.noarch.rpm
python3-3.9.19-20.cm2.x86_64.rpm
python3-devel-3.9.19-20.cm2.x86_64.rpm
python3-libs-3.9.19-20.cm2.x86_64.rpm
python3-setuptools-3.9.19-20.cm2.noarch.rpm
python3-pygments-2.4.2-7.cm2.noarch.rpm
which-2.21-8.cm2.x86_64.rpm
libselinux-3.2-1.cm2.x86_64.rpm
Expand Down
18 changes: 9 additions & 9 deletions toolkit/resources/manifests/package/toolchain_aarch64.txt
Original file line number Diff line number Diff line change
Expand Up @@ -510,28 +510,28 @@ procps-ng-devel-3.3.17-2.cm2.aarch64.rpm
procps-ng-lang-3.3.17-2.cm2.aarch64.rpm
pyproject-rpm-macros-1.0.0~rc1-4.cm2.noarch.rpm
python-markupsafe-debuginfo-2.1.0-1.cm2.aarch64.rpm
python3-3.9.19-19.cm2.aarch64.rpm
python3-3.9.19-20.cm2.aarch64.rpm
python3-audit-3.0.6-8.cm2.aarch64.rpm
python3-cracklib-2.9.7-5.cm2.aarch64.rpm
python3-curses-3.9.19-19.cm2.aarch64.rpm
python3-curses-3.9.19-20.cm2.aarch64.rpm
python3-Cython-0.29.33-2.cm2.aarch64.rpm
python3-debuginfo-3.9.19-19.cm2.aarch64.rpm
python3-devel-3.9.19-19.cm2.aarch64.rpm
python3-debuginfo-3.9.19-20.cm2.aarch64.rpm
python3-devel-3.9.19-20.cm2.aarch64.rpm
python3-gpg-1.16.0-2.cm2.aarch64.rpm
python3-jinja2-3.0.3-7.cm2.noarch.rpm
python3-libcap-ng-0.8.2-2.cm2.aarch64.rpm
python3-libs-3.9.19-19.cm2.aarch64.rpm
python3-libs-3.9.19-20.cm2.aarch64.rpm
python3-libxml2-2.10.4-11.cm2.aarch64.rpm
python3-lxml-4.9.1-1.cm2.aarch64.rpm
python3-magic-5.40-3.cm2.noarch.rpm
python3-markupsafe-2.1.0-1.cm2.aarch64.rpm
python3-newt-0.52.21-5.cm2.aarch64.rpm
python3-pip-3.9.19-19.cm2.noarch.rpm
python3-pip-3.9.19-20.cm2.noarch.rpm
python3-pygments-2.4.2-7.cm2.noarch.rpm
python3-rpm-4.18.0-4.cm2.aarch64.rpm
python3-setuptools-3.9.19-19.cm2.noarch.rpm
python3-test-3.9.19-19.cm2.aarch64.rpm
python3-tools-3.9.19-19.cm2.aarch64.rpm
python3-setuptools-3.9.19-20.cm2.noarch.rpm
python3-test-3.9.19-20.cm2.aarch64.rpm
python3-tools-3.9.19-20.cm2.aarch64.rpm
readline-8.1-1.cm2.aarch64.rpm
readline-debuginfo-8.1-1.cm2.aarch64.rpm
readline-devel-8.1-1.cm2.aarch64.rpm
Expand Down
18 changes: 9 additions & 9 deletions toolkit/resources/manifests/package/toolchain_x86_64.txt
Original file line number Diff line number Diff line change
Expand Up @@ -516,28 +516,28 @@ procps-ng-devel-3.3.17-2.cm2.x86_64.rpm
procps-ng-lang-3.3.17-2.cm2.x86_64.rpm
pyproject-rpm-macros-1.0.0~rc1-4.cm2.noarch.rpm
python-markupsafe-debuginfo-2.1.0-1.cm2.x86_64.rpm
python3-3.9.19-19.cm2.x86_64.rpm
python3-3.9.19-20.cm2.x86_64.rpm
python3-audit-3.0.6-8.cm2.x86_64.rpm
python3-cracklib-2.9.7-5.cm2.x86_64.rpm
python3-curses-3.9.19-19.cm2.x86_64.rpm
python3-curses-3.9.19-20.cm2.x86_64.rpm
python3-Cython-0.29.33-2.cm2.x86_64.rpm
python3-debuginfo-3.9.19-19.cm2.x86_64.rpm
python3-devel-3.9.19-19.cm2.x86_64.rpm
python3-debuginfo-3.9.19-20.cm2.x86_64.rpm
python3-devel-3.9.19-20.cm2.x86_64.rpm
python3-gpg-1.16.0-2.cm2.x86_64.rpm
python3-jinja2-3.0.3-7.cm2.noarch.rpm
python3-libcap-ng-0.8.2-2.cm2.x86_64.rpm
python3-libs-3.9.19-19.cm2.x86_64.rpm
python3-libs-3.9.19-20.cm2.x86_64.rpm
python3-libxml2-2.10.4-11.cm2.x86_64.rpm
python3-lxml-4.9.1-1.cm2.x86_64.rpm
python3-magic-5.40-3.cm2.noarch.rpm
python3-markupsafe-2.1.0-1.cm2.x86_64.rpm
python3-newt-0.52.21-5.cm2.x86_64.rpm
python3-pip-3.9.19-19.cm2.noarch.rpm
python3-pip-3.9.19-20.cm2.noarch.rpm
python3-pygments-2.4.2-7.cm2.noarch.rpm
python3-rpm-4.18.0-4.cm2.x86_64.rpm
python3-setuptools-3.9.19-19.cm2.noarch.rpm
python3-test-3.9.19-19.cm2.x86_64.rpm
python3-tools-3.9.19-19.cm2.x86_64.rpm
python3-setuptools-3.9.19-20.cm2.noarch.rpm
python3-test-3.9.19-20.cm2.x86_64.rpm
python3-tools-3.9.19-20.cm2.x86_64.rpm
readline-8.1-1.cm2.x86_64.rpm
readline-debuginfo-8.1-1.cm2.x86_64.rpm
readline-devel-8.1-1.cm2.x86_64.rpm
Expand Down
Loading