Skip to content

Commit 9496346

Browse files
sethmlarsonmiss-islington
authored andcommitted
gh-143930: Reject leading dashes in webbrowser URLs
(cherry picked from commit 82a24a4) Co-authored-by: Seth Michael Larson <seth@python.org>
1 parent 53b544a commit 9496346

File tree

3 files changed

+19
-0
lines changed

3 files changed

+19
-0
lines changed

Lib/test/test_webbrowser.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ def test_open(self):
6565
options=[],
6666
arguments=[URL])
6767

68+
def test_reject_dash_prefixes(self):
69+
browser = self.browser_class(name=CMD_NAME)
70+
with self.assertRaises(ValueError):
71+
browser.open(f"--key=val {URL}")
72+
6873

6974
class BackgroundBrowserCommandTest(CommandTestMixin, unittest.TestCase):
7075

Lib/webbrowser.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,12 @@ def open_new(self, url):
164164
def open_new_tab(self, url):
165165
return self.open(url, 2)
166166

167+
@staticmethod
168+
def _check_url(url):
169+
"""Ensures that the URL is safe to pass to subprocesses as a parameter"""
170+
if url and url.lstrip().startswith("-"):
171+
raise ValueError(f"Invalid URL: {url}")
172+
167173

168174
class GenericBrowser(BaseBrowser):
169175
"""Class for all browsers started with a command
@@ -181,6 +187,7 @@ def __init__(self, name):
181187

182188
def open(self, url, new=0, autoraise=True):
183189
sys.audit("webbrowser.open", url)
190+
self._check_url(url)
184191
cmdline = [self.name] + [arg.replace("%s", url)
185192
for arg in self.args]
186193
try:
@@ -201,6 +208,7 @@ def open(self, url, new=0, autoraise=True):
201208
cmdline = [self.name] + [arg.replace("%s", url)
202209
for arg in self.args]
203210
sys.audit("webbrowser.open", url)
211+
self._check_url(url)
204212
try:
205213
if sys.platform[:3] == 'win':
206214
p = subprocess.Popen(cmdline)
@@ -267,6 +275,7 @@ def _invoke(self, args, remote, autoraise, url=None):
267275

268276
def open(self, url, new=0, autoraise=True):
269277
sys.audit("webbrowser.open", url)
278+
self._check_url(url)
270279
if new == 0:
271280
action = self.remote_action
272281
elif new == 1:
@@ -358,6 +367,7 @@ class Konqueror(BaseBrowser):
358367

359368
def open(self, url, new=0, autoraise=True):
360369
sys.audit("webbrowser.open", url)
370+
self._check_url(url)
361371
# XXX Currently I know no way to prevent KFM from opening a new win.
362372
if new == 2:
363373
action = "newTab"
@@ -576,6 +586,7 @@ def register_standard_browsers():
576586
class WindowsDefault(BaseBrowser):
577587
def open(self, url, new=0, autoraise=True):
578588
sys.audit("webbrowser.open", url)
589+
self._check_url(url)
579590
try:
580591
os.startfile(url)
581592
except OSError:
@@ -596,6 +607,7 @@ def __init__(self, name='default'):
596607

597608
def open(self, url, new=0, autoraise=True):
598609
sys.audit("webbrowser.open", url)
610+
self._check_url(url)
599611
url = url.replace('"', '%22')
600612
if self.name == 'default':
601613
script = f'open location "{url}"' # opens in default browser
@@ -627,6 +639,7 @@ def open(self, url, new=0, autoraise=True):
627639
class IOSBrowser(BaseBrowser):
628640
def open(self, url, new=0, autoraise=True):
629641
sys.audit("webbrowser.open", url)
642+
self._check_url(url)
630643
# If ctypes isn't available, we can't open a browser
631644
if objc is None:
632645
return False
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Reject leading dashes in URLs passed to :func:`webbrowser.open`

0 commit comments

Comments
 (0)