Skip to content

Commit 996a010

Browse files
tomcruiseqisethmlarson
authored andcommitted
Reject leading dashes in webbrowser URLs (pythonGH-143931) (pythonGH-146359) Cherry-picked from Python 3.10: ad4d5ba (cherry picked from commit 82a24a4) Co-authored-by: Seth Michael Larson <seth@python.org>
1 parent b8b991c commit 996a010

File tree

3 files changed

+20
-0
lines changed

3 files changed

+20
-0
lines changed

Lib/test/test_webbrowser.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@ def test_open(self):
5555
options=[],
5656
arguments=[URL])
5757

58+
def test_reject_dash_prefixes(self):
59+
browser = self.browser_class(name=CMD_NAME)
60+
with self.assertRaises(ValueError):
61+
browser.open(f"--key=val {URL}")
62+
5863

5964
class BackgroundBrowserCommandTest(CommandTestMixin, unittest.TestCase):
6065

Lib/webbrowser.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,12 @@ def open_new(self, url):
154154
def open_new_tab(self, url):
155155
return self.open(url, 2)
156156

157+
@staticmethod
158+
def _check_url(url):
159+
"""Ensures that the URL is safe to pass to subprocesses as a parameter"""
160+
if url and url.lstrip().startswith("-"):
161+
raise ValueError(f"Invalid URL: {url}")
162+
157163

158164
class GenericBrowser(BaseBrowser):
159165
"""Class for all browsers started with a command
@@ -171,6 +177,7 @@ def __init__(self, name):
171177

172178
def open(self, url, new=0, autoraise=True):
173179
sys.audit("webbrowser.open", url)
180+
self._check_url(url)
174181
cmdline = [self.name] + [arg.replace("%s", url)
175182
for arg in self.args]
176183
try:
@@ -191,6 +198,7 @@ def open(self, url, new=0, autoraise=True):
191198
cmdline = [self.name] + [arg.replace("%s", url)
192199
for arg in self.args]
193200
sys.audit("webbrowser.open", url)
201+
self._check_url(url)
194202
try:
195203
if sys.platform[:3] == 'win':
196204
p = subprocess.Popen(cmdline)
@@ -256,6 +264,7 @@ def _invoke(self, args, remote, autoraise, url=None):
256264

257265
def open(self, url, new=0, autoraise=True):
258266
sys.audit("webbrowser.open", url)
267+
self._check_url(url)
259268
if new == 0:
260269
action = self.remote_action
261270
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"
@@ -441,6 +451,7 @@ def _remote(self, action):
441451

442452
def open(self, url, new=0, autoraise=True):
443453
sys.audit("webbrowser.open", url)
454+
self._check_url(url)
444455
if new:
445456
ok = self._remote("LOADNEW " + url)
446457
else:
@@ -599,6 +610,7 @@ def register_standard_browsers():
599610
class WindowsDefault(BaseBrowser):
600611
def open(self, url, new=0, autoraise=True):
601612
sys.audit("webbrowser.open", url)
613+
self._check_url(url)
602614
try:
603615
os.startfile(url)
604616
except OSError:
@@ -629,6 +641,7 @@ def __init__(self, name):
629641

630642
def open(self, url, new=0, autoraise=True):
631643
sys.audit("webbrowser.open", url)
644+
self._check_url(url)
632645
assert "'" not in url
633646
# hack for local urls
634647
if not ':' in url:
@@ -666,6 +679,7 @@ def __init__(self, name):
666679
self._name = name
667680

668681
def open(self, url, new=0, autoraise=True):
682+
self._check_url(url)
669683
if self._name == 'default':
670684
script = 'open location "%s"' % url.replace('"', '%22') # opens in default browser
671685
else:
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)