Skip to content

[3.10] gh-143930: Reject leading dashes in webbrowser URLs (GH-143931)#146359

Open
tomcruiseqi wants to merge 1 commit intopython:3.10from
tomcruiseqi:backport-82a24a4-3.10
Open

[3.10] gh-143930: Reject leading dashes in webbrowser URLs (GH-143931)#146359
tomcruiseqi wants to merge 1 commit intopython:3.10from
tomcruiseqi:backport-82a24a4-3.10

Conversation

@tomcruiseqi
Copy link

@tomcruiseqi tomcruiseqi commented Mar 24, 2026

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR backports a security hardening change to webbrowser to prevent option-injection style issues by rejecting URLs that begin with - (after leading whitespace) before passing them to browser launchers.

Changes:

  • Add BaseBrowser._check_url() to reject leading-dash URLs with a ValueError.
  • Invoke _check_url() from multiple open() implementations that launch browsers.
  • Add a regression test and a Security NEWS blurb.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
Misc/NEWS.d/next/Security/2026-01-16-12-04-49.gh-issue-143930.zYC5x3.rst Documents the security behavior change in webbrowser.open().
Lib/webbrowser.py Introduces URL validation and applies it to several browser controllers.
Lib/test/test_webbrowser.py Adds a test ensuring leading-dash inputs are rejected (currently for GenericBrowser).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

def _check_url(url):
"""Ensures that the URL is safe to pass to subprocesses as a parameter"""
if url and url.lstrip().startswith("-"):
raise ValueError(f"Invalid URL: {url}")
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ValueError message interpolates the raw URL, which can include control characters/newlines and makes logs/debug output ambiguous. Consider using a safer/clearer representation (e.g., url!r) and/or a message that specifically calls out “URLs must not start with '-' after leading whitespace”.

Suggested change
raise ValueError(f"Invalid URL: {url}")
raise ValueError(
f"Invalid URL {url!r}: URLs must not start with '-' after leading whitespace"
)

Copilot uses AI. Check for mistakes.
Comment on lines +157 to +161
@staticmethod
def _check_url(url):
"""Ensures that the URL is safe to pass to subprocesses as a parameter"""
if url and url.lstrip().startswith("-"):
raise ValueError(f"Invalid URL: {url}")
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_check_url() is only effective when each browser implementation calls it. Currently MacOSXOSAScript.open() and Grail.open() do not call _check_url(), so on macOS (default controller) and when Grail is available, webbrowser.open() can still accept leading-dash values. If the intent is to reject leading dashes for all webbrowser.open() calls, add _check_url() calls to those implementations (or enforce the check once in the module-level open() function).

Copilot uses AI. Check for mistakes.
Comment on lines +60 to +64
def test_reject_dash_prefixes(self):
browser = self.browser_class(name=CMD_NAME)
with self.assertRaises(ValueError):
browser.open(f"--key=val {URL}")

Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new test only exercises GenericBrowser.open(), but this change also adds _check_url() calls in several other controllers (e.g., BackgroundBrowser, UnixBrowser, Konqueror, and platform-specific implementations). Consider adding a small parametrized test (or a mixin-based loop) to assert that each affected browser_class.open() rejects leading-dash inputs, so the security behavior is covered across implementations.

Copilot uses AI. Check for mistakes.
(cherry picked from commit 82a24a4)

Co-authored-by: Seth Michael Larson <seth@python.org>
@tomcruiseqi tomcruiseqi force-pushed the backport-82a24a4-3.10 branch from 69fd15b to c84b32d Compare March 24, 2026 07:16
@tomcruiseqi tomcruiseqi changed the title [3.10] gh-143930: Reject leading dashes in webbrowser URLs [3.10] gh-143930: Reject leading dashes in webbrowser URLs (GH-143931) Mar 24, 2026
@bedevere-app bedevere-app bot added the type-security A security issue label Mar 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants