Skip to content

Commit b0fa074

Browse files
committed
gh-143930: Reject leading dashes in webbrowser URLs
1 parent 3e93225 commit b0fa074

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
@@ -67,6 +67,11 @@ def test_open(self):
6767
options=[],
6868
arguments=[URL])
6969

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

7176
class BackgroundBrowserCommandTest(CommandTestMixin, unittest.TestCase):
7277

Lib/webbrowser.py

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

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

167173
class GenericBrowser(BaseBrowser):
168174
"""Class for all browsers started with a command
@@ -180,6 +186,7 @@ def __init__(self, name):
180186

181187
def open(self, url, new=0, autoraise=True):
182188
sys.audit("webbrowser.open", url)
189+
self._check_url(url)
183190
cmdline = [self.name] + [arg.replace("%s", url)
184191
for arg in self.args]
185192
try:
@@ -200,6 +207,7 @@ def open(self, url, new=0, autoraise=True):
200207
cmdline = [self.name] + [arg.replace("%s", url)
201208
for arg in self.args]
202209
sys.audit("webbrowser.open", url)
210+
self._check_url(url)
203211
try:
204212
if sys.platform[:3] == 'win':
205213
p = subprocess.Popen(cmdline)
@@ -266,6 +274,7 @@ def _invoke(self, args, remote, autoraise, url=None):
266274

267275
def open(self, url, new=0, autoraise=True):
268276
sys.audit("webbrowser.open", url)
277+
self._check_url(url)
269278
if new == 0:
270279
action = self.remote_action
271280
elif new == 1:
@@ -357,6 +366,7 @@ class Konqueror(BaseBrowser):
357366

358367
def open(self, url, new=0, autoraise=True):
359368
sys.audit("webbrowser.open", url)
369+
self._check_url(url)
360370
# XXX Currently I know no way to prevent KFM from opening a new win.
361371
if new == 2:
362372
action = "newTab"
@@ -588,6 +598,7 @@ def register_standard_browsers():
588598
class WindowsDefault(BaseBrowser):
589599
def open(self, url, new=0, autoraise=True):
590600
sys.audit("webbrowser.open", url)
601+
self._check_url(url)
591602
try:
592603
os.startfile(url)
593604
except OSError:
@@ -608,6 +619,7 @@ def __init__(self, name='default'):
608619

609620
def open(self, url, new=0, autoraise=True):
610621
sys.audit("webbrowser.open", url)
622+
self._check_url(url)
611623
url = url.replace('"', '%22')
612624
if self.name == 'default':
613625
proto, _sep, _rest = url.partition(":")
@@ -664,6 +676,7 @@ def open(self, url, new=0, autoraise=True):
664676
class IOSBrowser(BaseBrowser):
665677
def open(self, url, new=0, autoraise=True):
666678
sys.audit("webbrowser.open", url)
679+
self._check_url(url)
667680
# If ctypes isn't available, we can't open a browser
668681
if objc is None:
669682
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)