Files
python312/CVE-2026-4786-webbrowser-open-action.patch
T
mcepl 65fde0babc Add CVE-2026-4786-webbrowser-open-action.patch
It fixes webbrowser %action substitution bypass of dash-prefix check
(bsc#1262319, CVE-2026-4786, gh#python/cpython#148169).
2026-04-25 12:58:27 +02:00

66 lines
3.0 KiB
Diff

From 1016d827af13ad302502b7b27b8479b08e524638 Mon Sep 17 00:00:00 2001
From: Stan Ulbrych <stan@python.org>
Date: Mon, 13 Apr 2026 20:02:52 +0100
Subject: [PATCH] [3.12] gh-148169: Fix webbrowser `%action` substitution
bypass of dash-prefix check (GH-148170) (cherry picked from commit
d22922c8a7958353689dc4763dd72da2dea03fff)
Co-authored-by: Stan Ulbrych <stan@python.org>
---
Lib/test/test_webbrowser.py | 9 +++++++++
Lib/webbrowser.py | 5 +++--
Misc/NEWS.d/next/Security/2026-03-31-09-15-51.gh-issue-148169.EZJzz2.rst | 2 ++
3 files changed, 14 insertions(+), 2 deletions(-)
create mode 100644 Misc/NEWS.d/next/Security/2026-03-31-09-15-51.gh-issue-148169.EZJzz2.rst
Index: Python-3.12.13/Lib/test/test_webbrowser.py
===================================================================
--- Python-3.12.13.orig/Lib/test/test_webbrowser.py 2026-04-25 12:58:18.907715078 +0200
+++ Python-3.12.13/Lib/test/test_webbrowser.py 2026-04-25 12:58:18.961715505 +0200
@@ -99,6 +99,15 @@
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 EdgeCommandTest(CommandTestMixin, unittest.TestCase):
Index: Python-3.12.13/Lib/webbrowser.py
===================================================================
--- Python-3.12.13.orig/Lib/webbrowser.py 2026-04-25 12:58:18.907998903 +0200
+++ Python-3.12.13/Lib/webbrowser.py 2026-04-25 12:58:18.961859987 +0200
@@ -267,7 +267,6 @@
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:
@@ -281,7 +280,9 @@
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)
Index: Python-3.12.13/Misc/NEWS.d/next/Security/2026-03-31-09-15-51.gh-issue-148169.EZJzz2.rst
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ Python-3.12.13/Misc/NEWS.d/next/Security/2026-03-31-09-15-51.gh-issue-148169.EZJzz2.rst 2026-04-25 12:58:18.961975715 +0200
@@ -0,0 +1,2 @@
+A bypass in :mod:`webbrowser` allowed URLs prefixed with ``%action`` to pass
+the dash-prefix safety check.