Created
May 28, 2026 17:44
-
-
Save stavfx/2d16ffcbc7913e28e585568e7045aa09 to your computer and use it in GitHub Desktop.
Apple quarantine bypass
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
| #!/bin/bash | |
| # install-unquarantine-mount.sh | |
| # | |
| # Builds a small AppleScript applet that strips the com.apple.quarantine | |
| # attribute from a DMG before mounting it, so apps installed from that | |
| # DMG launch without the "no Open button" Gatekeeper dialog. | |
| # | |
| # Usage: | |
| # bash install-unquarantine-mount.sh | |
| # | |
| # After install: | |
| # In Finder, right-click any .dmg -> Get Info -> Open with -> | |
| # "Unquarantine & Mount" -> Change All... | |
| # | |
| # Security note: doing this systematically bypasses Apple's notarization | |
| # check for DMGs you double-click. Only install if you understand that. | |
| set -e | |
| APP_DIR="$HOME/Applications" | |
| APP_PATH="$APP_DIR/Unquarantine & Mount.app" | |
| mkdir -p "$APP_DIR" | |
| rm -rf "$APP_PATH" | |
| TMP_SCRIPT="$(mktemp -t unquarantine).applescript" | |
| cat > "$TMP_SCRIPT" <<'APPLESCRIPT' | |
| on open theFiles | |
| repeat with f in theFiles | |
| set p to POSIX path of f | |
| try | |
| do shell script "/usr/bin/xattr -dr com.apple.quarantine " & quoted form of p | |
| end try | |
| do shell script "/usr/bin/open -a 'DiskImageMounter' " & quoted form of p | |
| end repeat | |
| end open | |
| APPLESCRIPT | |
| osacompile -o "$APP_PATH" "$TMP_SCRIPT" | |
| rm -f "$TMP_SCRIPT" | |
| PLIST="$APP_PATH/Contents/Info.plist" | |
| # osacompile already creates CFBundleDocumentTypes as a generic droplet entry; | |
| # prepend a specific entry that advertises this app as a DMG handler so Finder | |
| # offers it under "Open With". | |
| /usr/libexec/PlistBuddy -c "Add :CFBundleDocumentTypes:0 dict" "$PLIST" | |
| /usr/libexec/PlistBuddy -c "Add :CFBundleDocumentTypes:0:CFBundleTypeName string 'Disk Image'" "$PLIST" | |
| /usr/libexec/PlistBuddy -c "Add :CFBundleDocumentTypes:0:CFBundleTypeRole string Viewer" "$PLIST" | |
| /usr/libexec/PlistBuddy -c "Add :CFBundleDocumentTypes:0:LSItemContentTypes array" "$PLIST" | |
| /usr/libexec/PlistBuddy -c "Add :CFBundleDocumentTypes:0:LSItemContentTypes:0 string com.apple.disk-image" "$PLIST" | |
| # Stable bundle id so Launch Services can track it across rebuilds. | |
| /usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier local.unquarantine-mount" "$PLIST" 2>/dev/null \ | |
| || /usr/libexec/PlistBuddy -c "Add :CFBundleIdentifier string local.unquarantine-mount" "$PLIST" | |
| # Force Launch Services to notice the new handler immediately. | |
| LSREGISTER="/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister" | |
| "$LSREGISTER" -f "$APP_PATH" | |
| # Make this app the default handler for .dmg files. The only thing that | |
| # actually moves the Launch Services database is calling | |
| # LSSetDefaultRoleHandlerForContentType -- editing | |
| # ~/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist | |
| # directly looks like it should work but is a dead end; LS keeps its own | |
| # cache and ignores manual edits. We call the API via Swift because JXA's | |
| # auto-bridge of JS strings to CFString fails for this function (paramErr). | |
| SWIFT_BIN="$(xcrun -f swift 2>/dev/null || true)" | |
| if [ -n "$SWIFT_BIN" ] && [ -x "$SWIFT_BIN" ]; then | |
| "$SWIFT_BIN" - <<'SWIFT' | |
| import Foundation | |
| import CoreServices | |
| let bid = "local.unquarantine-mount" as CFString | |
| // Set the parent UTI and the UDIF subtype; macOS doesn't always propagate | |
| // parent -> child for inherited handlers, so we set both explicitly. | |
| for t in ["com.apple.disk-image", "com.apple.disk-image-udif"] { | |
| let s = LSSetDefaultRoleHandlerForContentType(t as CFString, .all, bid) | |
| if s != 0 { | |
| FileHandle.standardError.write(Data("warning: LSSetDefaultRoleHandler failed for \(t): \(s)\n".utf8)) | |
| } | |
| } | |
| SWIFT | |
| echo | |
| echo "Installed: $APP_PATH" | |
| echo "Default handler for .dmg files: local.unquarantine-mount" | |
| else | |
| echo | |
| echo "Installed: $APP_PATH" | |
| echo | |
| echo "Xcode Command Line Tools weren't found, so the default-handler" | |
| echo "step was skipped. Either run 'xcode-select --install' and re-run" | |
| echo "this script, or set the default by hand: in Finder, right-click" | |
| echo "any .dmg -> Get Info -> Open with -> 'Unquarantine & Mount' ->" | |
| echo "Change All..." | |
| fi |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I made this ^ because I got sick of this:

install at your own risk.