gh-137586: Replace 'osascript' with 'open' on macOS#146439
Open
secengjeff wants to merge 8 commits intopython:mainfrom
Open
gh-137586: Replace 'osascript' with 'open' on macOS#146439secengjeff wants to merge 8 commits intopython:mainfrom
secengjeff wants to merge 8 commits intopython:mainfrom
Conversation
…ate MacOSXOSAScript
Add a new MacOSX class that opens URLs via subprocess.run(['/usr/bin/open', ...])
instead of piping AppleScript to osascript. For named browsers, /usr/bin/open -a
<name> is used; for the default browser, /usr/bin/open <url> defers directly to
the OS URL handler.
MacOSXOSAScript is deprecated with a DeprecationWarning pointing users to MacOSX.
register_standard_browsers() is updated to use MacOSX for all macOS registrations.
osascript is a general-purpose scripting interpreter that is routinely blocked on
managed endpoints due to its abuse potential, causing webbrowser.open() to fail
silently. /usr/bin/open is Apple's purpose-built URL-opening primitive and carries
no such restrictions. This also eliminates the PATH-injection vector in the existing
os.popen("osascript", "w") call.
…pt deprecation Add MacOSXTest covering default browser open, named browser open, and failure case (non-zero returncode). Add MacOSXOSAScriptDeprecationTest verifying that instantiating MacOSXOSAScript emits a DeprecationWarning. All tests mock subprocess.run.
|
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
…press Sphinx lookup
- Add test_default to MacOSXTest asserting webbrowser.get() returns MacOSX - Remove test_default from MacOSXOSAScriptTest (no longer the registered default) - Suppress DeprecationWarning in MacOSXOSAScriptTest setUp and test_explicit_browser using warnings.catch_warnings() so tests for OSAScript behaviour still run cleanly - Add warnings import
…ia OS handler For non-http(s) URLs (e.g. file://), /usr/bin/open dispatches via the OS file handler, which would launch an .app bundle rather than open it in a browser. Fix this by routing non-http(s) URLs through the browser explicitly using /usr/bin/open -b <bundle-id>. Named browsers use a static bundle ID map (Chrome, Firefox, Safari, Chromium, Opera, Edge). Unknown named browsers fall back to -a. For the default browser, the bundle ID is resolved at runtime via the Objective-C runtime using NSWorkspace.URLForApplicationToOpenURL, the same lookup MacOSXOSAScript performed via AppleScript. Falls back to direct open if ctypes is unavailable. http/https URLs with the default browser continue to use /usr/bin/open directly, as macOS always routes these to the registered browser.
…ult_browser_bundle_id NSWorkspace is an AppKit class and is not registered in the ObjC runtime until AppKit is loaded. Without the explicit LoadLibrary call, objc_getClass returns nil for NSWorkspace, causing the entire lookup to silently fall back to /usr/bin/open without -b.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Replaces
MacOSXOSAScript, which pipes AppleScript toosascript, with a newMacOSXclass that calls/usr/bin/opendirectly viasubprocess.run.MacOSXOSAScriptis deprecated with aDeprecationWarningpointing users toMacOSX.Why
osascriptis a general-purpose AppleScript interpreter and a known LOObin (Living Off the Land binary). Because it can execute arbitrary code, it is routinely blocked by endpoint security tooling on managed Macs. This causeswebbrowser.open()to break for users of any Python application that depends on thewebbrowserlibrary, with no obvious connection toosascriptas the cause./usr/bin/openis Apple's purpose-built URL-opening primitive. It passes the URL directly to the OS-registered URL handler with no scripting interpreter involved, and is not subject to the same endpoint security restrictions.Security
This fixes gh-137586. The existing
os.popen("osascript", "w")call resolves viaPATH, creating a PATH-injection vector. The open PR for that issue (#137584) proposes switching to/usr/bin/osascript; this change eliminates the dependency entirely.File injection safety
/usr/bin/open <url>dispatches via the OS file handler, which means afile://URL pointing to an.appbundle or installer would launch it rather than open it in a browser. To prevent this, non-http(s) URLs are routed through the browser explicitly using/usr/bin/open -b <bundle-id>, ensuring the URL is always handled by a browser regardless of scheme.Named browsers use a static bundle ID map for common browsers (
com.google.Chrome,org.mozilla.firefox,com.apple.Safari, etc.). Unknown named browsers fall back to-a. For the default browser, the bundle ID is resolved at runtime via the Objective-C runtime using the sameNSWorkspace.URLForApplicationToOpenURLlookup thatMacOSXOSAScriptperformed via AppleScript, with a graceful fallback to directopenif ctypes is unavailable.Named browser support
MacOSXOSAScriptusedtell application "<name>"to target specific browsers.MacOSXpreserves this with/usr/bin/open -b <bundle-id>for known browsers and/usr/bin/open -a <name>for others.Testing
Tested locally on macOS with the default browser and named browsers (Safari, Chrome). Unit tests added covering: default http/https open, non-http URL bundle ID routing, bundle ID lookup fallback, named browser with known bundle ID, named browser fallback to
-a, failure case, and the deprecation warning.Changes
Lib/webbrowser.py: add_macos_default_browser_bundle_id(), addMacOSXwith bundle ID map, deprecateMacOSXOSAScript, updateregister_standard_browsers()Lib/test/test_webbrowser.py: addMacOSXTestandMacOSXOSAScriptDeprecationTestDoc/library/webbrowser.rst: add.. deprecated:: 3.14entry forMacOSXOSAScriptFixes gh-137586.