Skip to content

Commit ceac1ef

Browse files
[3.11] gh-143930: Reject leading dashes in webbrowser URLs (GH-143931) (GH-146364)
(cherry picked from commit 82a24a4) Co-authored-by: Seth Michael Larson <seth@python.org>
1 parent 86a67f8 commit ceac1ef

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

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

6368
class BackgroundBrowserCommandTest(CommandTestMixin, unittest.TestCase):
6469

Lib/webbrowser.py

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

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

159165
class GenericBrowser(BaseBrowser):
160166
"""Class for all browsers started with a command
@@ -172,6 +178,7 @@ def __init__(self, name):
172178

173179
def open(self, url, new=0, autoraise=True):
174180
sys.audit("webbrowser.open", url)
181+
self._check_url(url)
175182
cmdline = [self.name] + [arg.replace("%s", url)
176183
for arg in self.args]
177184
try:
@@ -192,6 +199,7 @@ def open(self, url, new=0, autoraise=True):
192199
cmdline = [self.name] + [arg.replace("%s", url)
193200
for arg in self.args]
194201
sys.audit("webbrowser.open", url)
202+
self._check_url(url)
195203
try:
196204
if sys.platform[:3] == 'win':
197205
p = subprocess.Popen(cmdline)
@@ -257,6 +265,7 @@ def _invoke(self, args, remote, autoraise, url=None):
257265

258266
def open(self, url, new=0, autoraise=True):
259267
sys.audit("webbrowser.open", url)
268+
self._check_url(url)
260269
if new == 0:
261270
action = self.remote_action
262271
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"
@@ -442,6 +452,7 @@ def _remote(self, action):
442452

443453
def open(self, url, new=0, autoraise=True):
444454
sys.audit("webbrowser.open", url)
455+
self._check_url(url)
445456
if new:
446457
ok = self._remote("LOADNEW " + url)
447458
else:
@@ -605,6 +616,7 @@ def register_standard_browsers():
605616
class WindowsDefault(BaseBrowser):
606617
def open(self, url, new=0, autoraise=True):
607618
sys.audit("webbrowser.open", url)
619+
self._check_url(url)
608620
try:
609621
os.startfile(url)
610622
except OSError:
@@ -637,6 +649,7 @@ def __init__(self, name):
637649

638650
def open(self, url, new=0, autoraise=True):
639651
sys.audit("webbrowser.open", url)
652+
self._check_url(url)
640653
assert "'" not in url
641654
# hack for local urls
642655
if not ':' in url:
@@ -689,6 +702,7 @@ def _name(self, val):
689702

690703
def open(self, url, new=0, autoraise=True):
691704
sys.audit("webbrowser.open", url)
705+
self._check_url(url)
692706
if self.name == 'default':
693707
script = 'open location "%s"' % url.replace('"', '%22') # opens in default browser
694708
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)