Hacktricks-skills macos-sandbox
macOS Sandbox security expert. Use this skill whenever the user asks about macOS sandboxing, sandbox profiles, SBPL, sandbox-exec, container inspection, sandbox extensions, or any macOS security isolation mechanism. Trigger for questions about sandbox bypasses, profile creation, process inspection, or debugging sandboxed applications.
git clone https://github.com/abelrguezr/hacktricks-skills
skills/macos-hardening/macos-security-and-privilege-escalation/macos-security-protections/macos-sandbox/macos-sandbox/SKILL.MDmacOS Sandbox Security
A comprehensive guide to understanding, working with, and debugging macOS Sandbox security mechanisms.
What is macOS Sandbox?
macOS Sandbox (originally called Seatbelt) limits applications to only the allowed actions specified in their Sandbox profile. This ensures applications access only expected resources.
Key facts:
- Any app with entitlement
runs inside the sandboxcom.apple.security.app-sandbox - All App Store apps have this entitlement
- Apple binaries are usually sandboxed
- Uses MACF (Mandatory Access Control Framework) hooks for most syscalls
Core Components
| Component | Path | Purpose |
|---|---|---|
| Kernel Extension | | Core sandbox enforcement |
| Private Framework | | Sandbox APIs |
| Daemon | | Userland sandbox manager |
| Containers | | App-specific isolated directories |
Understanding Containers
Every sandboxed application has its own container:
# List all containers ls -l ~/Library/Containers # Inspect a specific container cd ~/Library/Containers/{CFBundleIdentifier} ls -la
Container structure:
- Container configuration.com.apple.containermanagerd.metadata.plist
- App data directory (mimics home folder structure)Data/
Important: Even with symlinks to Desktop, Downloads, etc., the app needs explicit permissions in the
.plist file's RedirectablePaths to access them.
Sandbox Profiles (SBPL)
Sandbox profiles use Sandbox Profile Language (SBPL), based on Scheme:
(version 1) ; Profile version (deny default) ; Default action when no rule matches (allow network*) ; Allow all network operations (allow file-read* ; Allow file reads from: (subpath "/Users/username/") (literal "/tmp/afile") (regex #"^/private/etc/.*") ) (allow mach-lookup ; Allow specific Mach port (global-name "com.apple.analyticsd") )
Common operations:
- All file operationsfile*
- File read operationsfile-read*
- File write operationsfile-write*
- Process executionprocess*
- Network operationsnetwork*
- Mach port accessmach-lookup
Creating and Testing Sandbox Profiles
Basic Profile Creation
# Create a profile file cat > /tmp/test.sb << 'EOF' (version 1) (deny default) (allow file* (literal "/tmp/test.txt")) (allow process* (literal "/usr/bin/touch")) (allow file-read-data (literal "/")) EOF # Run command with profile sandbox-exec -f /tmp/test.sb /usr/bin/touch /tmp/test.txt
Common Profile Patterns
Minimal network access:
(version 1) (deny default) (allow network-client-connect) (allow file-read* (subpath "~/"))
File server (read-only):
(version 1) (deny default) (allow network-server) (allow file-read* (subpath "/var/www/"))
Development with temp access:
(version 1) (deny default) (allow file* (subpath "/tmp/")) (allow file* (subpath "~/Downloads/")) (allow process-exec (subpath "/usr/bin/"))
Inspecting Sandboxed Processes
Using sbtool
# Check if PID can access a file sbtool <pid> file /tmp # Check Mach port access sbtool <pid> mach # Full inspection of sandbox state sbtool <pid> inspect # Check all permissions sbtool <pid> all
Using log show
# View recent sandbox denials log show --style syslog --predicate 'eventMessage contains[c] "sandbox"' --last 30s # Filter for specific process log show --predicate 'processImagePath contains "AppName" and eventMessage contains "sandbox"' --last 1h
Container Configuration
# Get container metadata (requires FDA) plutil -convert xml1 ~/Library/Containers/{bundle-id}/.com.apple.containermanagerd.metadata.plist -o - # Look for: # - SandboxProfileData (compiled profile) # - Entitlements (granted permissions) # - RedirectablePaths (accessible paths)
Sandbox Tracing
Via Profile
# Create trace profile cat > /tmp/trace.sb << 'EOF' (version 1) (trace /tmp/trace.out) EOF # Run with tracing sandbox-exec -f /tmp/trace.sb /bin/ls # View trace output cat /tmp/trace.out
Via Command Line
# Inline trace sandbox-exec -t /tmp/trace.out -p "(version 1)" /bin/ls
System Sandbox Profiles
Locations:
- System profiles/usr/share/sandbox/
- Application profiles/System/Library/Sandbox/Profiles/
- SIP platform profile/System/Library/Sandbox/rootless.conf
Common profiles:
- Default App Store app profileapplication.sb
- Platform policy (SIP)platform.sb
- Various system daemon profiles*.sb
Sandbox Extensions
Extensions grant additional privileges to sandboxed processes:
Extension types:
- File accesssandbox_extension_issue_file
- Mach port accesssandbox_extension_issue_mach
- I/O Kit accesssandbox_extension_issue_iokit_user_client_class
- Generic extensionsandbox_extension_issue_generic
Key points:
- Extensions are usually granted by allowed processes (e.g.,
for photos)tccd - Extension tokens are long hex strings encoding permissions
- Tokens can be consumed by multiple processes
- Related to entitlements - some entitlements auto-grant extensions
Debugging Sandbox Issues
Common Problems and Solutions
Problem: Command fails with "deny(1) process-exec*" Solution: Add
(allow process* (literal "/path/to/command"))
Problem: File access denied Solution: Add appropriate file permission:
(allow file-read-data (literal "/path/to/file")) (allow file-write-data (literal "/path/to/file"))
Problem: Dynamic library loading fails Solution: Add dyld and library paths:
(allow file-read-data (literal "/usr/lib/dyld")) (allow file-read-data (literal "/usr/lib/"))
Debug Workflow
-
Check the denial:
log show --predicate 'eventMessage contains "sandbox"' --last 1m -
Identify the operation:
- Need process permissionprocess-exec*
- Need file read permissionfile-read-metadata
- Need file data permissionfile-read-data
-
Add minimal permission: Start with
and add only what's needed(deny default) -
Test incrementally: Add one permission at a time to identify what's required
Security Considerations
Quarantine Attribute
Files created/modified by sandboxed apps get the quarantine attribute, preventing Gatekeeper bypass:
# Check quarantine attribute xattr -l /path/to/file | grep com.apple.quarantine # Remove quarantine (if needed) xattr -d com.apple.quarantine /path/to/file
Entitlements
Key entitlements:
- Enables sandboxingcom.apple.security.app-sandbox
- Network server accesscom.apple.security.network.server
- Custom SBPL (Apple-approved only)com.apple.security.temporary-exception.sbpl
- Keychain accesskeychain-access-groups
SIP Integration
System Integrity Protection uses sandbox:
- Platform profile in
/System/Library/Sandbox/rootless.conf - Protects system directories
- Cannot be disabled without boot flags
Quick Reference
| Task | Command |
|---|---|
| Run with profile | |
| Run with inline profile | |
| Trace sandbox checks | |
| Inspect process | |
| View sandbox logs | |
| List containers | |
| View container config | |
Best Practices
- Start restrictive: Begin with
and add permissions as needed(deny default) - Use literals over wildcards: More specific = more secure
- Test incrementally: Add one permission at a time
- Check logs: Always verify what's being denied
- Document profiles: Comment your SBPL files
- Review extensions: Understand what extensions your app needs