Skip to content

Commit c84b32d

Browse files
sethmlarsontomcruiseqi
authored andcommitted
[3.10] gh-143930: Reject leading dashes in webbrowser URLs
(cherry picked from commit 82a24a4) Co-authored-by: Seth Michael Larson <seth@python.org>
1 parent ba6eba5 commit c84b32d

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
@@ -57,6 +57,11 @@ def test_open(self):
5757
options=[],
5858
arguments=[URL])
5959

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

6166
class BackgroundBrowserCommandTest(CommandTestMixin, unittest.TestCase):
6267

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:
@@ -603,6 +614,7 @@ def register_standard_browsers():
603614
class WindowsDefault(BaseBrowser):
604615
def open(self, url, new=0, autoraise=True):
605616
sys.audit("webbrowser.open", url)
617+
self._check_url(url)
606618
try:
607619
os.startfile(url)
608620
except OSError:
@@ -633,6 +645,7 @@ def __init__(self, name):
633645

634646
def open(self, url, new=0, autoraise=True):
635647
sys.audit("webbrowser.open", url)
648+
self._check_url(url)
636649
assert "'" not in url
637650
# hack for local urls
638651
if not ':' in url:
@@ -670,6 +683,7 @@ def __init__(self, name):
670683
self._name = name
671684

672685
def open(self, url, new=0, autoraise=True):
686+
self._check_url(url)
673687
if self._name == 'default':
674688
script = 'open location "%s"' % url.replace('"', '%22') # opens in default browser
675689
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)