Skip to content
New issue

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

Enable App Sandbox on macOS builds #10478

Draft
wants to merge 1 commit into
base: develop
Choose a base branch
from

Conversation

caesarw
Copy link

@caesarw caesarw commented Mar 20, 2024

This pull request enables the App Sandbox feature, as well as explicitly enabling the following entitlements:

  • USB device access (for hardware keys)
  • User selected file access (r/w)
  • Network client (for HIBP and icon download)
  • Application groups (for IPC with keepassxc-proxy)

The following entitlement has not been added/tested:

  • Entitlement for the auto-type feature (related to accessibility access)
  • And more ...

This commit is a WIP, so expect bugs.

Enabling the App Sandbox on KeePassXC can further enhance the security of the app. If some malicious code/payload is inserted into a KeePassXC database, and somehow get executed, the sandbox can protect the rest of the OS from being further compromised.

Screenshots

N/A

Testing strategy

  1. Build, bundle and sign the app on macOS
  2. Run and test all above mentioned features that's related to entitlements.

Type of change

  • ✅ New feature (change that adds functionality)

This commit enables the App Sandbox feature, as well as explicitly enabling the following entitlements
* USB device access (for hardware keys)
* User selected file access (r/w)
* Network client (for HIBP and icon download)
* Application groups (for IPC with keepassxc-proxy)

This commit is a WIP, so expect bugs.
@phoerious
Copy link
Member

App sandbox breaks browser integration, because there are no fitting entitlements for it.

@Kingston1
Copy link
Contributor

Kingston1 commented Mar 23, 2024

App sandbox breaks browser integration, because there are no fitting entitlements for it.

Not true. Apple just is not great at documenting them and they are not visible in the dumb and limited default Xcode UI for sandboxing. Here's a large list of examples, all allowed even in app store. Not a comprehensive list, but serves as an example. Pick and choose depending on your use cases. com.apple.security.temporary-exception.sbpl key is especially interesting because it allows full support of the actual .sb sandbox file format exotic cases.

<dict>
    <key>com.apple.developer.networking.networkextension</key>
    <array>
        <string>content-filter-provider</string>
    </array>
    <key>com.apple.developer.system-extension.install</key>
    <true/>
    <key>com.apple.developer.team-identifier</key>
    <string>TEAMID</string>
    <key>com.apple.security.files.user-selected.read-only</key>
    <true/>
    <key>com.apple.security.network.client</key>
    <true/>
    <key>com.apple.security.network.server</key>
    <true/>
    <key>com.apple.security.temporary-exception.files.absolute-path.read-only</key>
    <array>
        <string>/FullPath/</string>
        <string>/FullPath/file</string>
    </array>
    <key>com.apple.security.temporary-exception.files.absolute-path.read-write</key>
    <array>
        <string>/FullPath/</string>
        <string>/FullPath/file</string>
    </array>
    <key>com.apple.security.temporary-exception.files.home-relative-path.read-only</key>
    <array>
        <string>/FullPath/</string>
        <string>/FullPath/file</string>
    </array>
    <key>com.apple.security.temporary-exception.files.home-relative-path.read-write</key>
    <array>
        <string>/FullPath/</string>
        <string>/FullPath/file</string>
    </array>
    <key>com.apple.security.temporary-exception.mach-lookup.global-name</key>
    <array>
        <string>com.name.mach-service-your-xpc-thing</string>
    </array>
    <key>com.apple.security.temporary-exception.sbpl</key>
    <array>
        <string>(allow user-preference-read (preference-domain &quot;com.pref.domain&quot;))</string>
        <string>(allow authorization-right-obtain (right-name &quot;system.privilege.admin&quot;))</string>
        <string>(allow file-read-data             (subpath &quot;/private/tmp&quot;))</string>
        <string>(allow file-write*                (home-subpath &quot;/Library/Application Support/Stuff&quot;))</string>
        <string>(allow file-read*                 (home-subpath &quot;&quot;))</string>
        <string>(allow file-read-xattr)</string>
        <string>(allow file-write-unlink)</string>
        <string>(allow file-ioctl                 (regex #&quot;^/dev/ttys&quot;))</string>
        <string>(allow system-fsctl               (fsctl-command (_IO &quot;J&quot; 72)))</string>
        <string>(allow process-exec* (path-literal &quot;/Applications/someapp.app/Contents/MacOS/someapp&quot;) (with no-sandbox))</string>
    </array>
    <key>com.apple.security.temporary-exception.shared-preference.read-only</key>
    <array>
        <string>com.shared.preference.name</string>
    </array>
    <key>com.apple.developer.networking.vpn.api</key>
    <array>
        <string>allow-vpn</string>
    </array>
</dict>

@Kingston1
Copy link
Contributor

Kingston1 commented Mar 23, 2024

Further, it can get tricky finding what exactly you would need to allow in the sandbox rule set. The best way is to run console app and simply work through the entire app and its functionality. You need to use all the features including browser extensions. Then stop the console app recording and filter for "processName sandbox", so in this case it should be "keepassxc sandbox". This will show all the sandbox violations and usually (but not consistently), which exact sandbox rule was violated. Then simply allow this using the above .plist entitlements format. For a complex app the list can grow quite long.

@droidmonkey
Copy link
Member

Seems like by the time you finish all this work you pretty much nullify the point of a sandbox. Perhaps not entirely, but pretty darn close.

@phoerious
Copy link
Member

All the ones I could find in the docs were either for specific default locations or required the user to explicitly select a path with the open file dialogue. If these work without user interaction for arbitrary paths, I'm happy to use them.

@Kingston1
Copy link
Contributor

Seems like by the time you finish all this work you pretty much nullify the point of a sandbox. Perhaps not entirely, but pretty darn close.

Not quite. The point is to protect against unintended breaches and thus potential vulnerabilities. The entitlements essentially document the application security model. Only allow what you know is necessary. If a vulnerability pops up, it does not escape the sandbox.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants