Add CVE-2024-6923-follow-up-EOL-email-headers.patch

It is a follow-up to the previous fix of CVE-2024-6923 further encoding
EOL possibly hidden in email headers (bsc#1257181).
This commit is contained in:
2026-01-27 17:58:02 +01:00
parent 97fc2dfa82
commit 4c387b3dba
3 changed files with 121 additions and 0 deletions

View File

@@ -0,0 +1,110 @@
From 1132e45e8b588cd89bd168583afa37ba7c9f0afa Mon Sep 17 00:00:00 2001
From: Denis Ledoux <dle@odoo.com>
Date: Mon, 27 Oct 2025 17:47:59 +0100
Subject: [PATCH 1/3] gh-144125: email: verify headers are sound in
BytesGenerator
GH-122233 added an implementation to `Generator`
to refuse to serialize (write) headers that
are unsafely folded or delimited.
This revision adds the same implementation
to `BytesGenerator`, so it gets the same safety protections
for unsafely folded or delimited headers
Co-authored-by: Denis Ledoux <5822488+beledouxdenis@users.noreply.github.com>
Co-authored-by: Petr Viktorin <302922+encukou@users.noreply.github.com>
Co-authored-by: Bas Bloemsaat <1586868+basbloemsaat@users.noreply.github.com>
---
Lib/email/generator.py | 12 +++++++++-
Lib/test/test_email/test_generator.py | 4 ++-
Lib/test/test_email/test_policy.py | 6 ++++-
Misc/NEWS.d/next/Security/2026-01-21-12-34-05.gh-issue-144125.TAz5uo.rst | 4 +++
4 files changed, 23 insertions(+), 3 deletions(-)
create mode 100644 Misc/NEWS.d/next/Security/2026-01-21-12-34-05.gh-issue-144125.TAz5uo.rst
Index: Python-3.15.0a3/Lib/email/generator.py
===================================================================
--- Python-3.15.0a3.orig/Lib/email/generator.py 2026-01-27 17:26:06.289940190 +0100
+++ Python-3.15.0a3/Lib/email/generator.py 2026-01-27 17:26:14.361081031 +0100
@@ -22,6 +22,7 @@
NLCRE = re.compile(r'\r\n|\r|\n')
fcre = re.compile(r'^From ', re.MULTILINE)
NEWLINE_WITHOUT_FWSP = re.compile(r'\r\n[^ \t]|\r[^ \n\t]|\n[^ \t]')
+NEWLINE_WITHOUT_FWSP_BYTES = re.compile(br'\r\n[^ \t]|\r[^ \n\t]|\n[^ \t]')
class Generator:
@@ -429,7 +430,16 @@
# This is almost the same as the string version, except for handling
# strings with 8bit bytes.
for h, v in msg.raw_items():
- self._fp.write(self.policy.fold_binary(h, v))
+ folded = self.policy.fold_binary(h, v)
+ if self.policy.verify_generated_headers:
+ linesep = self.policy.linesep.encode()
+ if not folded.endswith(linesep):
+ raise HeaderWriteError(
+ f'folded header does not end with {linesep!r}: {folded!r}')
+ if NEWLINE_WITHOUT_FWSP_BYTES.search(folded.removesuffix(linesep)):
+ raise HeaderWriteError(
+ f'folded header contains newline: {folded!r}')
+ self._fp.write(folded)
# A blank line always separates headers from body
self.write(self._NL)
Index: Python-3.15.0a3/Lib/test/test_email/test_generator.py
===================================================================
--- Python-3.15.0a3.orig/Lib/test/test_email/test_generator.py 2026-01-27 17:26:08.009520772 +0100
+++ Python-3.15.0a3/Lib/test/test_email/test_generator.py 2026-01-27 17:26:14.363103139 +0100
@@ -313,7 +313,7 @@
self.assertEqual(s.getvalue(), self.typ(expected))
def test_verify_generated_headers(self):
- """gh-121650: by default the generator prevents header injection"""
+ # gh-121650: by default the generator prevents header injection
class LiteralHeader(str):
name = 'Header'
def fold(self, **kwargs):
@@ -334,6 +334,8 @@
with self.assertRaises(email.errors.HeaderWriteError):
message.as_string()
+ with self.assertRaises(email.errors.HeaderWriteError):
+ message.as_bytes()
class TestBytesGenerator(TestGeneratorBase, TestEmailBase):
Index: Python-3.15.0a3/Lib/test/test_email/test_policy.py
===================================================================
--- Python-3.15.0a3.orig/Lib/test/test_email/test_policy.py 2026-01-27 17:26:08.021649854 +0100
+++ Python-3.15.0a3/Lib/test/test_email/test_policy.py 2026-01-27 17:26:14.363238384 +0100
@@ -296,7 +296,7 @@
policy.fold("Subject", subject)
def test_verify_generated_headers(self):
- """Turning protection off allows header injection"""
+ # Turning protection off allows header injection
policy = email.policy.default.clone(verify_generated_headers=False)
for text in (
'Header: Value\r\nBad: Injection\r\n',
@@ -319,6 +319,10 @@
message.as_string(),
f"{text}\nBody",
)
+ self.assertEqual(
+ message.as_bytes(),
+ f"{text}\nBody".encode(),
+ )
# XXX: Need subclassing tests.
# For adding subclassed objects, make sure the usual rules apply (subclass
Index: Python-3.15.0a3/Misc/NEWS.d/next/Security/2026-01-21-12-34-05.gh-issue-144125.TAz5uo.rst
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ Python-3.15.0a3/Misc/NEWS.d/next/Security/2026-01-21-12-34-05.gh-issue-144125.TAz5uo.rst 2026-01-27 17:26:14.362392400 +0100
@@ -0,0 +1,4 @@
+:mod:`~email.generator.BytesGenerator` will now refuse to serialize (write) headers
+that are unsafely folded or delimited; see
+:attr:`~email.policy.Policy.verify_generated_headers`. (Contributed by Bas
+Bloemsaat and Petr Viktorin in :gh:`121650`).

View File

@@ -1,3 +1,10 @@
-------------------------------------------------------------------
Tue Jan 27 16:31:12 UTC 2026 - Matej Cepl <mcepl@cepl.eu>
- Add CVE-2024-6923-follow-up-EOL-email-headers.patch which is
a follow-up to the previous fix of CVE-2024-6923 further
encoding EOL possibly hidden in email headers (bsc#1257181).
-------------------------------------------------------------------
Wed Jan 21 18:02:37 UTC 2026 - Matej Cepl <mcepl@cepl.eu>

View File

@@ -228,6 +228,10 @@ Patch42: gh139257-Support-docutils-0.22.patch
# PATCH-FIX-UPSTREAM longer-time-test_thread_time.patch gh#python/cpython!143558 mcepl@suse.com
# tolerate 100 ms instead of 20 ms to support slow CIs.
Patch43: longer-time-test_thread_time.patch
# PATCH-FIX-UPSTREAM CVE-2024-6923-follow-up-EOL-email-headers.patch bsc#1257181 mcepl@suse.com
# Encode newlines in headers when using ByteGenerator
# patch from gh#python/cpython#144125
Patch44: CVE-2024-6923-follow-up-EOL-email-headers.patch
#### Python 3.15 DEVELOPMENT PATCHES
BuildRequires: autoconf-archive
BuildRequires: automake