From 372e4a409e047803fcad1751ff52e98a11e9ea64c8dbaf3e30a971b51bd3253b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C4=9Bj=20Cepl?= Date: Wed, 4 Feb 2026 01:58:39 +0100 Subject: [PATCH] Add CVE-2026-0865-wsgiref-ctrl-chars.patch fixing bsc#1257042 (CVE-2026-0865) rejecting control characters in wsgiref.headers.Headers, which could be abused for injecting false HTTP headers. --- CVE-2026-0865-wsgiref-ctrl-chars.patch | 68 ++++++++++++++++++++++++++ python315.changes | 6 ++- python315.spec | 3 ++ 3 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 CVE-2026-0865-wsgiref-ctrl-chars.patch diff --git a/CVE-2026-0865-wsgiref-ctrl-chars.patch b/CVE-2026-0865-wsgiref-ctrl-chars.patch new file mode 100644 index 0000000..ec419c2 --- /dev/null +++ b/CVE-2026-0865-wsgiref-ctrl-chars.patch @@ -0,0 +1,68 @@ +From e7f180b4c21576f52c08933a184d84dc4b47e00e Mon Sep 17 00:00:00 2001 +From: Seth Michael Larson +Date: Fri, 16 Jan 2026 10:54:09 -0600 +Subject: [PATCH 1/2] Add 'test.support' fixture for C0 control characters + +--- + Lib/test/test_wsgiref.py | 12 +++++++++- + Lib/wsgiref/headers.py | 3 ++ + Misc/NEWS.d/next/Security/2026-01-16-11-07-36.gh-issue-143916.dpWeOD.rst | 2 + + 3 files changed, 16 insertions(+), 1 deletion(-) + +Index: Python-3.15.0a3/Lib/test/test_wsgiref.py +=================================================================== +--- Python-3.15.0a3.orig/Lib/test/test_wsgiref.py 2026-02-04 01:52:45.393433768 +0100 ++++ Python-3.15.0a3/Lib/test/test_wsgiref.py 2026-02-04 01:52:52.928458181 +0100 +@@ -1,6 +1,6 @@ + from unittest import mock + from test import support +-from test.support import socket_helper ++from test.support import socket_helper, control_characters_c0 + from test.test_httpservers import NoLogRequestHandler + from unittest import TestCase + from wsgiref.util import setup_testing_defaults +@@ -503,6 +503,16 @@ + '\r\n' + ) + ++ def testRaisesControlCharacters(self): ++ headers = Headers() ++ for c0 in control_characters_c0(): ++ self.assertRaises(ValueError, headers.__setitem__, f"key{c0}", "val") ++ self.assertRaises(ValueError, headers.__setitem__, "key", f"val{c0}") ++ self.assertRaises(ValueError, headers.add_header, f"key{c0}", "val", param="param") ++ self.assertRaises(ValueError, headers.add_header, "key", f"val{c0}", param="param") ++ self.assertRaises(ValueError, headers.add_header, "key", "val", param=f"param{c0}") ++ ++ + class ErrorHandler(BaseCGIHandler): + """Simple handler subclass for testing BaseHandler""" + +Index: Python-3.15.0a3/Lib/wsgiref/headers.py +=================================================================== +--- Python-3.15.0a3.orig/Lib/wsgiref/headers.py 2026-02-04 01:52:45.666384529 +0100 ++++ Python-3.15.0a3/Lib/wsgiref/headers.py 2026-02-04 01:52:52.928606420 +0100 +@@ -9,6 +9,7 @@ + # existence of which force quoting of the parameter value. + import re + tspecials = re.compile(r'[ \(\)<>@,;:\\"/\[\]\?=]') ++_control_chars_re = re.compile(r'[\x00-\x1F\x7F]') + + def _formatparam(param, value=None, quote=1): + """Convenience function to format and return a key=value pair. +@@ -41,6 +42,8 @@ + def _convert_string_type(self, value): + """Convert/check value type.""" + if type(value) is str: ++ if _control_chars_re.search(value): ++ raise ValueError("Control characters not allowed in headers") + return value + raise AssertionError("Header names/values must be" + " of type str (got {0})".format(repr(value))) +Index: Python-3.15.0a3/Misc/NEWS.d/next/Security/2026-01-16-11-07-36.gh-issue-143916.dpWeOD.rst +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ Python-3.15.0a3/Misc/NEWS.d/next/Security/2026-01-16-11-07-36.gh-issue-143916.dpWeOD.rst 2026-02-04 01:52:52.928707130 +0100 +@@ -0,0 +1,2 @@ ++Reject C0 control characters within wsgiref.headers.Headers fields, values, ++and parameters. diff --git a/python315.changes b/python315.changes index 57b4f34..db83dc1 100644 --- a/python315.changes +++ b/python315.changes @@ -1,10 +1,14 @@ ------------------------------------------------------------------- -Tue Feb 3 15:39:21 UTC 2026 - Matej Cepl +Wed Feb 4 00:53:37 UTC 2026 - Matej Cepl - Add CVE-2025-12781-b64decode-alt-chars.patch fixing bsc#1257108 (CVE-2025-12781) combining gh#python/cpython!141061, gh#python/cpython!141128, and gh#python/cpython!141153. All `*b64decode` functions should not accept non-altchars. +- Add CVE-2026-0865-wsgiref-ctrl-chars.patch fixing bsc#1257042 + (CVE-2026-0865) rejecting control characters in + wsgiref.headers.Headers, which could be abused for injecting + false HTTP headers. ------------------------------------------------------------------- Tue Jan 27 16:31:12 UTC 2026 - Matej Cepl diff --git a/python315.spec b/python315.spec index 0e97c7c..f2de91e 100644 --- a/python315.spec +++ b/python315.spec @@ -241,6 +241,9 @@ Patch46: CVE-2026-0672-http-hdr-inject-cookie-Morsel.patch # PATCH-FIX-UPSTREAM CVE-2025-12781-b64decode-alt-chars.patch bsc#1257108 mcepl@suse.com # Fix decoding with non-standard Base64 alphabet gh#python/cpython#125346 Patch47: CVE-2025-12781-b64decode-alt-chars.patch +# PATCH-FIX-UPSTREAM CVE-2026-0865-wsgiref-ctrl-chars.patch bsc#1257042 mcepl@suse.com +# Reject control characters in wsgiref.headers.Headers +Patch48: CVE-2026-0865-wsgiref-ctrl-chars.patch #### Python 3.15 DEVELOPMENT PATCHES BuildRequires: autoconf-archive BuildRequires: automake