diff --git a/CVE-2026-4786.patch b/CVE-2026-4786.patch new file mode 100644 index 0000000000000000000000000000000000000000..af0338dee2645fefc07cb6a780fdfdd9b92d10f8 --- /dev/null +++ b/CVE-2026-4786.patch @@ -0,0 +1,64 @@ +From f4654824ae0850ac87227fb270f9057477946769 Mon Sep 17 00:00:00 2001 +From: Stan Ulbrych +Date: Mon, 13 Apr 2026 22:41:51 +0100 +Subject: [PATCH] [3.11] gh-148169: Fix webbrowser `%action` substitution + bypass of dash-prefix check (GH-148170) (#148520) + +(cherry picked from commit d22922c8a7958353689dc4763dd72da2dea03fff) +--- + Lib/test/test_webbrowser.py | 8 ++++++++ + Lib/webbrowser.py | 5 +++-- + .../2026-03-31-09-15-51.gh-issue-148169.EZJzz2.rst | 2 ++ + 3 files changed, 13 insertions(+), 2 deletions(-) + create mode 100644 Misc/NEWS.d/next/Security/2026-03-31-09-15-51.gh-issue-148169.EZJzz2.rst + +diff --git a/Lib/test/test_webbrowser.py b/Lib/test/test_webbrowser.py +index 74eca81c707ead..f10f54e4d4ec32 100644 +--- a/Lib/test/test_webbrowser.py ++++ b/Lib/test/test_webbrowser.py +@@ -103,6 +103,14 @@ def test_open_new_tab(self): + options=[], + arguments=[URL]) + ++ def test_reject_action_dash_prefixes(self): ++ browser = self.browser_class(name=CMD_NAME) ++ with self.assertRaises(ValueError): ++ browser.open('%action--incognito') ++ # new=1: action is "--new-window", so "%action" itself expands to ++ # a dash-prefixed flag even with no dash in the original URL. ++ with self.assertRaises(ValueError): ++ browser.open('%action', new=1) + + class MozillaCommandTest(CommandTestMixin, unittest.TestCase): + +diff --git a/Lib/webbrowser.py b/Lib/webbrowser.py +index ce6ec9a27d7d8b..9819a4ecf6d43e 100755 +--- a/Lib/webbrowser.py ++++ b/Lib/webbrowser.py +@@ -265,7 +265,6 @@ def _invoke(self, args, remote, autoraise, url=None): + + def open(self, url, new=0, autoraise=True): + sys.audit("webbrowser.open", url) +- self._check_url(url) + if new == 0: + action = self.remote_action + elif new == 1: +@@ -279,7 +278,9 @@ def open(self, url, new=0, autoraise=True): + raise Error("Bad 'new' parameter to open(); " + + "expected 0, 1, or 2, got %s" % new) + +- args = [arg.replace("%s", url).replace("%action", action) ++ self._check_url(url.replace("%action", action)) ++ ++ args = [arg.replace("%action", action).replace("%s", url) + for arg in self.remote_args] + args = [arg for arg in args if arg] + success = self._invoke(args, True, autoraise, url) +diff --git a/Misc/NEWS.d/next/Security/2026-03-31-09-15-51.gh-issue-148169.EZJzz2.rst b/Misc/NEWS.d/next/Security/2026-03-31-09-15-51.gh-issue-148169.EZJzz2.rst +new file mode 100644 +index 00000000000000..45cdeebe1b6d64 +--- /dev/null ++++ b/Misc/NEWS.d/next/Security/2026-03-31-09-15-51.gh-issue-148169.EZJzz2.rst +@@ -0,0 +1,2 @@ ++A bypass in :mod:`webbrowser` allowed URLs prefixed with ``%action`` to pass ++the dash-prefix safety check. diff --git a/python3.spec b/python3.spec index 13d1d37672db953f5a55ccd9e1bc87e15d1f1ecf..429f7924a5c9fdeb57dd1dbe7c8cbe7fc61e64ee 100644 --- a/python3.spec +++ b/python3.spec @@ -1,4 +1,4 @@ -%define anolis_release 21 +%define anolis_release 22 %global pybasever 3.11 # pybasever without the dot: @@ -305,6 +305,8 @@ Patch0034: 0034-bugfix-for-CVE-2026-4519.patch Patch0035: CVE-2025-11468.patch #https://github.com/python/cpython/commit/e20c6c9667c99ecaab96e1a2b3767082841ffc8b Patch0036: CVE-2026-6100.patch +# https://github.com/python/cpython/commit/f4654824ae0850ac87227fb270f9057477946769 +Patch0037: CVE-2026-4786.patch # ========================================== # Descriptions, and metadata for subpackages @@ -1577,6 +1579,9 @@ CheckPython optimized # ====================================================== %changelog +* Tue Apr 14 2026 yangjinlin01 - 3.11.6-22 +- Fix CVE-2026-4786 + * Tue Apr 14 2026 yangjinlin01 - 3.11.6-21 - Fix CVE-2026-6100