| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,8 @@ | ||
| """Interfaces for launching and remotely controlling web browsers.""" | ||
| # Maintained by Georg Brandl. | ||
|
|
||
| import builtins # because we override open | ||
| import os | ||
| lazy import plistlib | ||
|
Comment thread
Copy link
Copy Markdown
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality
Sorry, something went wrong.
All reactions
|
||
| import shlex | ||
| import shutil | ||
| import sys | ||
| Expand Down Expand Up | @@ -492,10 +493,15 @@ def register_standard_browsers(): | |
| _tryorder = [] | ||
|
|
||
| if sys.platform == 'darwin': | ||
| register("MacOSX", None, MacOSXOSAScript('default')) | ||
|
Comment thread
gpshead marked this conversation as resolved.
|
||
| register("chrome", None, MacOSXOSAScript('google chrome')) | ||
| register("firefox", None, MacOSXOSAScript('firefox')) | ||
| register("safari", None, MacOSXOSAScript('safari')) | ||
| register("MacOS", None, MacOS('default')) | ||
| register("MacOSX", None, MacOS('default')) # backward compat alias | ||
| register("chrome", None, MacOS('google chrome')) | ||
| register("chromium", None, MacOS('chromium')) | ||
| register("firefox", None, MacOS('firefox')) | ||
| register("safari", None, MacOS('safari')) | ||
| register("opera", None, MacOS('opera')) | ||
| register("microsoft-edge", None, MacOS('microsoft edge')) | ||
| register("brave", None, MacOS('brave browser')) | ||
| # macOS can use below Unix support (but we prefer using the macOS | ||
| # specific stuff) | ||
|
|
||
| Expand Down Expand Up | @@ -614,8 +620,80 @@ def open(self, url, new=0, autoraise=True): | |
| # | ||
|
|
||
| if sys.platform == 'darwin': | ||
| def _macos_default_browser_bundle_id(): | ||
|
Comment thread
gpshead marked this conversation as resolved.
|
||
| """Return the bundle ID of the default web browser. | ||
|
|
||
| Reads the LaunchServices preferences file that macOS maintains | ||
| when the user sets a default browser. Returns 'com.apple.Safari' | ||
| if the file is absent or no https handler is recorded, because on | ||
| a fresh macOS installation Safari is the default browser and the | ||
| LaunchServices plist is not written until the user explicitly | ||
| changes their default browser. | ||
| """ | ||
| plist = os.path.expanduser( | ||
| '~/Library/Preferences/com.apple.LaunchServices/' | ||
| 'com.apple.launchservices.secure.plist' | ||
| ) | ||
| try: | ||
| with builtins.open(plist, 'rb') as f: | ||
| data = plistlib.load(f) | ||
|
Comment thread
gpshead marked this conversation as resolved.
|
||
| for handler in data.get('LSHandlers', []): | ||
| if handler.get('LSHandlerURLScheme') == 'https': | ||
| return (handler.get('LSHandlerRoleAll') | ||
| or handler.get('LSHandlerRoleViewer')) | ||
| except (OSError, KeyError, ValueError): | ||
| pass | ||
| return 'com.apple.Safari' | ||
|
|
||
| class MacOS(BaseBrowser): | ||
| """Launcher class for macOS browsers, using /usr/bin/open. | ||
|
|
||
| For http/https URLs with the default browser, /usr/bin/open is called | ||
| directly; macOS routes these to the registered browser. | ||
|
|
||
| For all other URL schemes (e.g. file://) and for named browsers, | ||
| /usr/bin/open -b <bundle-id> is used so that the URL is always passed | ||
| to a browser application rather than dispatched by the OS file handler. | ||
| This prevents file injection attacks where a file:// URL pointing to an | ||
| executable bundle could otherwise be launched by the OS. | ||
|
|
||
| Named browsers with known bundle IDs use -b; unknown names fall back | ||
| to -a. | ||
| """ | ||
|
|
||
| _BUNDLE_IDS = { | ||
| 'google chrome': 'com.google.Chrome', | ||
| 'firefox': 'org.mozilla.firefox', | ||
| 'safari': 'com.apple.Safari', | ||
| 'chromium': 'org.chromium.Chromium', | ||
| 'opera': 'com.operasoftware.Opera', | ||
|
Comment thread
hugovk marked this conversation as resolved.
|
||
| 'microsoft edge': 'com.microsoft.edgemac', | ||
| 'brave browser': 'com.brave.Browser', | ||
| } | ||
|
|
||
| def open(self, url, new=0, autoraise=True): | ||
| sys.audit("webbrowser.open", url) | ||
| self._check_url(url) | ||
| if self.name == 'default': | ||
| proto, sep, _ = url.partition(':') | ||
| if sep and proto.lower() in {'http', 'https'}: | ||
| cmd = ['/usr/bin/open', url] | ||
| else: | ||
| bundle_id = _macos_default_browser_bundle_id() | ||
| cmd = ['/usr/bin/open', '-b', bundle_id, url] | ||
| else: | ||
| bundle_id = self._BUNDLE_IDS.get(self.name.lower()) | ||
| if bundle_id: | ||
| cmd = ['/usr/bin/open', '-b', bundle_id, url] | ||
| else: | ||
| cmd = ['/usr/bin/open', '-a', self.name, url] | ||
| proc = subprocess.run(cmd, stderr=subprocess.DEVNULL) | ||
| return proc.returncode == 0 | ||
|
|
||
| class MacOSXOSAScript(BaseBrowser): | ||
| def __init__(self, name='default'): | ||
| import warnings | ||
| warnings._deprecated("webbrowser.MacOSXOSAScript", remove=(3, 17)) | ||
| super().__init__(name) | ||
|
|
||
| def open(self, url, new=0, autoraise=True): | ||
| Expand Down | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| Add :class:`!MacOS` to :mod:`webbrowser` for macOS, which opens URLs via | ||
| ``/usr/bin/open`` instead of piping AppleScript to ``osascript``. | ||
| Deprecate :class:`!MacOSXOSAScript` in favour of :class:`!MacOS`. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| Fix a PATH-injection vulnerability in :mod:`webbrowser` on macOS where | ||
| ``osascript`` was invoked without an absolute path. The new :class:`!MacOS` | ||
| class uses ``/usr/bin/open`` directly, eliminating the dependency on | ||
| ``osascript`` entirely. |
| Back | FazBrowse Home | New Git URL |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low QualityPlease list alphabetically, after typing
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.