macos沙盒机制默认禁用所有权限,仅通过entitlements文件和info.plist显式声明的权限才有效;未声明的api调用静默失败或报operation not permitted,三道防线包括严格声明entitlements、同步配置info.plist开关、运行时使用安全路径api。

macOS 本身不会让沙盒应用“请求非法权限”,它通过强制机制直接阻止越权行为——这不是靠拦截请求,而是从设计上让非法权限根本不存在、无法声明、也无法生效。
关键在于:沙盒应用的权限边界由 entitlements 文件和 Info.plist 共同定义,系统在启动时校验签名与授权配置;未声明的能力,连调用接口都会静默失败或触发 Operation not permitted 错误。
要确保沙盒应用不越界,核心是三道防线:
严格限制 entitlements 声明
沙盒应用能做什么,完全取决于你显式写入 .entitlements 文件的内容。系统会拒绝任何未列明的权限,哪怕代码里调用了相关 API:
- 删除所有非必要键,如
com.apple.security.network.server(除非真需监听端口) - 避免使用
temporary-exception类宽泛绕过项,它们在 macOS 12+ 已被大幅削弱,且 Mac App Store 审核必拒 - 网络权限必须按需二选一:仅发起请求就只加
network.client;仅提供服务才加network.server
Info.plist 中禁用隐式扩展能力
即使 entitlements 写对了,Info.plist 缺失对应开关,权限仍无效:
-
com.apple.security.files.user-selected.read-write必须设为true,否则 NSOpenPanel 选中的目录也无法持久访问 -
com.apple.security.assets.photos等资源类权限,必须配合 Photos.framework 的实际调用,否则系统不激活该通道 - Xcode Capabilities 页面勾选后,务必手动检查生成的 plist,防止自动配置遗漏或覆盖
运行时主动规避越权路径
沙盒不是“等你犯错再报错”,而是让某些路径从一开始就不可达:
- 不硬编码
~/Documents、/etc/hosts或/usr/bin等路径,这些在沙盒内解析后直接返回 nil 或 Permission Denied - 不尝试用
sudo、launchctl或osascript绕过沙盒调用系统工具——这些进程本身不受当前沙盒约束,但其子进程仍受限制,且多数操作会被 TCC 拦截 - 使用
FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)替代字符串拼接路径,确保始终落在合法容器内
系统不会给你“请求非法权限”的机会。所谓“禁止”,其实是默认关闭全部门,只为你亲手打开的那几扇留一条缝——关好没开的门,比拦住撞门的人更可靠。











