forked from pool/python312
65fde0babc
It fixes webbrowser %action substitution bypass of dash-prefix check (bsc#1262319, CVE-2026-4786, gh#python/cpython#148169).
66 lines
3.0 KiB
Diff
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.
|