macOS 27 阻止 App 访问其他 App 的数据:会出问题的地方与修复方法

macOSTahoe ·
macOS 27 阻止 App 访问其他 App 的数据:会出问题的地方与修复方法

macOS 27 在不询问的情况下拒绝 App 访问其他 App 的数据,并停止加载被隔离的 LaunchAgents。哪些功能会失效、如何授予访问权限、什么情况下不该授予。

自 macOS Sonoma 起,当一个 App 试图读取另一个 App 的私有数据时,系统会弹出提示:「App」想访问其他 App 的数据。 你可以选择允许或拒绝,无论出了什么问题,你都清楚原因。macOS 27 Golden Gate 取消了这条提示。现在访问默认被拒绝,且不再询问。想要数据的那个 App 只会得到空结果或「Operation not permitted」错误。你只有在某个功能悄悄失效时才会发现问题。

同一版本中还有三项相关改动指向同一个方向:XProtect 现在可以阻止访问恶意软件常窃取的数据,App 不再能直接读取隐私数据库,launchd 也拒绝加载带有隔离标记的属性列表文件。本指南将逐一引用 Apple 发布说明的原文来解释这些改动,展示如何检查你的 Mac 上受到哪些影响,并说明何时该、何时不该主动授予访问权限。

核心要点

  • 不再弹窗提示。 在 macOS 27 中,访问其他开发者的 App 数据容器和 App 组容器「默认被拒绝」,并在**隐私与安全性(Privacy & Security)**设置中管理。Apple 的发布说明将此改动列在系统完整性保护(System Integrity Protection)一节下。
  • 命令行工具是最棘手的情况。 Apple 列出了一个已知问题:没有 bundle ID 的进程无法被授予对某个 App 数据的访问权限。文档给出的变通方法是「在需求存续期间」授予完全磁盘访问权限。
  • XProtect 现在会守护「常被针对」的数据。 Apple 没有公开具体清单,因此即使某个工具此前一直能顺利读取某些 App 数据,现在也可能被拒绝。
  • App 不再能直接读取 TCC 隐私数据库。 那些通过检查 TCC.db 来报告权限的脚本和工具,需要换一种方式。
  • 被隔离的 LaunchAgents 不再加载。 在我们检查的这台 Mac 上,~/Library/LaunchAgents 中 20 个代理里有 9 个带有隔离属性——全部是三款第三方浏览器写入的更新程序代理。

变化过程:从弹窗提示到默认拒绝

Apple 一直在逐步收紧这个领域:

版本对其他开发者 App 数据的访问
macOS 13 Ventura 及更早版本基本对任何以你身份运行的进程开放
macOS 14 Sonoma受保护;用户会看到一条提示,询问是否允许访问「其他 App 的数据」
macOS 15 Sequoia保护范围扩展到 App 组容器
macOS 27 Golden Gate默认拒绝且不再提示;在隐私与安全性设置中管理

macOS 27 发布说明中系统完整性保护一节的原文如下:

访问其他开发者团队的 App 数据容器和 App 组容器中的文件时,系统不再提示用户进行授权;此类访问默认被拒绝,用户可以在隐私与安全性设置中进行管理。

这句话里有两个关键词决定了你是否会受影响。开发者团队:这条规则针对的是来自不同开发者的 App。同一开发者旗下的一套 App 仍然可以共享同一个组容器,因为它们由同一个团队签名。容器:这条规则覆盖的是 App 存放在你的 Library 中的沙盒数据文件夹,不包括你的 Documents 文件夹、桌面或你自己保存的文件——这些有各自独立的「文件与文件夹」权限,并未按这种方式发生变化。

什么算是「其他 App 的数据」

沙盒化的 App 会把私有文件保存在你主目录下的两个位置:

  • ~/Library/Containers/ —— 每个沙盒化 App 对应一个文件夹,以 bundle ID 命名,App 的实际数据存放在 Data/ 下
  • ~/Library/Group Containers/ —— 同一开发者旗下多个 App 共享的文件夹,命名方式为 group.… 或以开发者团队 ID 开头

列出这些文件夹名称本身是无害的操作,也能反映出规模。在我们使用的这台仍运行 Tahoe 26.5.2 的 Mac 上:

ls ~/Library/Containers | wc -l                    # 956
ls ~/Library/Group\ Containers | wc -l             # 187
ls ~/Library/Group\ Containers | grep -vc '^group\.'   # 70 named with a team ID

也就是说,共有 956 个 App 容器和 187 个组容器,其中每一个现在都默认对所有其他开发者的 App 关闭访问。这在大多数情况下没有问题:一个行为规范的 App 本来就不该去读取另一个 App 的数据库。真正的麻烦在于那些本来合法地替你读取这些数据的工具。

出问题时是什么样子

这种失败不会弹出对话框,只会以症状的形式体现出来。最常见的几种:

症状可能原因
在 Terminal 中对 ~/Library/Containers/…/Data 或 ~/Library/Group Containers/ 下的路径执行操作,出现 ls: … : Operation not permitted负责该 shell 的 App(Terminal、iTerm 或你的 IDE)没有该 App 数据的访问权限
备份、同步或导出工具跳过了某个 App 的数据,或报告「permission denied」该工具没有被授权读取那个容器
导入工具在另一个 App 中找不到任何可导入的内容被静默拒绝;导入工具看到的是空文件夹或不存在的文件夹
启动器、剪贴板或自动化工具失去了原本能读取其他 App 数据的功能同样是被拒绝访问,表现为结果缺失
由 cron 或 launchd 运行的脚本,在昨天还能读取的路径上失败没有 bundle ID 的命令行进程——见下文的已知问题

「Operation not permitted」(EPERM)是 macOS 隐私控制阻止文件访问时返回的标准错误。它不代表文件不存在,也不代表用 sudo 就能解决——隐私保护对 root 同样生效。

正确的授权方式

Apple 把这项控制放在**系统设置 → 隐私与安全性(Privacy & Security)中,下文提到的已知问题专门针对文件与文件夹(Files & Folders)**面板。现在对其他 App 数据的访问权限就是在这里按 App 逐一授予的,而不再通过一次性弹窗。

普通 App 的处理方式

  1. 打开系统设置 → 隐私与安全性 → 文件与文件夹。
  2. 找到需要该权限的 App 并展开它。
  3. 只允许它实际需要的具体数据,而不是更宽泛的访问权限。

macOS 27 上该面板的具体布局可能和 Tahoe 有所不同。Apple 的说明描述的是权限在哪里管理,而不是逐步点击的路径。原则始终不变:只授予能让功能正常运作所需的最小权限。

如果某个 App 的文档告诉你改为授予完全磁盘访问权限(Full Disk Access),那也可行——完全磁盘访问权限同样覆盖 App 数据容器。但它也覆盖你主目录下的其他所有内容,包括邮件、信息和 Safari 的数据,因此应该把它留给那些工作本身就是读取整个磁盘的工具:备份软件、磁盘分析工具之类。

脚本、cron 任务与命令行工具

Apple 在这里列出了一个已知问题:

在「文件与文件夹」面板中,没有 bundle ID 的进程无法被授予对其他开发者团队拥有的特定 App 数据容器或 App 组容器的访问权限。

变通方法:先考虑该访问是否确有必要。如果确实需要,就在需求存续期间为该进程授予完全磁盘访问权限。

「没有 bundle ID 的进程」指的是任何普通可执行文件:Python 解释器、由 launchd 运行的 shell 脚本、Homebrew 安装的二进制文件、由 cron 启动的守护进程。关键在于它是怎么被启动的:

  • 从 Terminal 运行:隐私判定会归属到 Terminal(或 iTerm、你的 IDE)身上,而这些 App 确实有 bundle ID。给这个 App 授权,通常就能覆盖你在其中运行的命令。
  • 由 launchd 或 cron 运行:没有可归属的 App。进程本身需要这项权限,根据已知问题的说明,这意味着要为该二进制文件授予完全磁盘访问权限。

要把一个命令行二进制文件加入完全磁盘访问权限列表,在列表中点击 +,按下 ⌘⇧G,粘贴路径(例如 /opt/homebrew/bin/python3 或 /usr/sbin/cron),然后添加它。Apple 的措辞——「在需求存续期间」——值得照字面理解:为这项任务授权,用完就移除。一个拥有完全磁盘访问权限的解释器,会把这项权限带给它运行的每一个脚本。

一个权限面板,正在为某个工具授予对单个 App 数据文件夹的有限访问权限

XProtect 这一层

同一节中的第二条说明,增加了一层不取决于「谁在请求」的保护:

XProtect 现在可能会限制对恶意软件常见目标数据的访问。访问其他开发者团队的 App 所创建的文件,可能默认被拒绝,但用户可以在隐私与安全性设置中进行管理。

Apple 没有说明哪些数据算作「常被针对」。安全研究人员已经充分记录了 Mac 信息窃取类恶意软件会寻找的目标:保存了密码和 Cookie 的浏览器配置文件、加密货币钱包数据,以及消息类 App 的会话文件。可以合理推测 XProtect 的清单与这些高度重合,但这终究只是推测。

对你而言,实际的影响是:一个原本合法读取(比如)另一个 App 会话或配置文件数据的工具,即使你已经授予了看起来正确的权限,在 macOS 27 上仍可能被拒绝。如果遇到这种情况,先去隐私与安全性里检查是否有一条待处理的条目。如果没有,就值得去问问该工具的开发者是否已经在 macOS 27 上测试过——修复可能需要由他们那一侧完成。

App 不再能读取隐私数据库

TCC(Transparency, Consent and Control,透明度、同意与控制)数据库记录着你允许哪些 App 使用摄像头、麦克风、屏幕录制、文件等权限。每个用户各自的副本位于 ~/Library/Application Support/com.apple.TCC/TCC.db。多年以来,拥有完全磁盘访问权限的工具都可以直接读取它来报告权限状况。

macOS 27 发布说明中「TCC 弃用项」一节写道:

App 不能再直接访问本地 TCC 数据库。

即便在 Tahoe 上,读取它也需要完全磁盘访问权限。在我们的测试 Mac 上,一个没有该权限的 shell 会得到:

sqlite3 ~/Library/Application\ Support/com.apple.TCC/TCC.db "select service from access limit 1"
# Error: unable to open database ".../com.apple.TCC/TCC.db": authorization denied

在 macOS 27 上,这条直接路径对所有 App 都被关闭了。会受到影响的是:

  • Mac 管理员:他们的合规脚本或资产清点扩展会查询 TCC.db 来报告权限状况。官方支持的路径是设备管理工具的隐私偏好设置策略控制(PPPC)报告功能,而不是直接读数据库。
  • 工具类软件:通过读取该文件向你展示「哪个 App 拥有哪些权限」。
  • 恶意软件:它们读取这个数据库来摸清自己已经能够到达的范围。这正是这项改动的原因。

对于你自己的 Mac,系统设置 → 隐私与安全性仍然是查看和撤销权限的地方。每个类别下都会列出持有该权限的 App。

另一个悄悄发生的改动:被隔离的 LaunchAgents

这项改动与 App 数据无关,但失效的方式如出一辙——悄无声息——而且实际上它对我们测试 Mac 的影响,比本文提到的其他任何改动都大。发布说明中「Launch Daemons and Agents」一节写道:

launchd 不再支持加载带有隔离扩展属性的 launchd 属性列表文件。

LaunchAgent 是位于 ~/Library/LaunchAgents 中的一个小型 .plist 文件,用于告诉 launchd 在登录时或按计划启动某个程序:更新程序、同步辅助工具、菜单栏工具等。隔离属性(com.apple.quarantine)是 macOS 附加给从互联网下载的文件的标记——也会附加给那些由本身受隔离规则约束的 App 所创建的文件。

检查只需要一个循环:

for f in ~/Library/LaunchAgents/*.plist /Library/LaunchAgents/*.plist /Library/LaunchDaemons/*.plist; do
  xattr "$f" 2>/dev/null | grep -q com.apple.quarantine && echo "QUARANTINED  $f"
done

在我们的测试 Mac 上:

文件夹属性列表数量被隔离数量
~/Library/LaunchAgents209
/Library/LaunchAgents80
/Library/LaunchDaemons270

这 9 个被隔离的文件全部是更新程序代理——每款各三个——由三款基于 Chromium 的第三方浏览器创建。隔离值的第三个字段会写明创建该文件的 App 名称:

xattr -p com.apple.quarantine ~/Library/LaunchAgents/some.agent.plist
# 0081;<timestamp>;<name of the app that wrote it>;<id>

其中至少有一个如今仍在 Tahoe 上被加载并运行。按照 Apple 的说明,在 macOS 27 上这些代理将无法加载,因此这些浏览器的后台更新程序会悄悄停止运作。我们尚未在 Golden Gate 本身上验证这一点,厂商也可能已经改变了各自代理的写入方式。但这正是那种会持续数月都无人察觉的故障:没有任何明显的失败,浏览器只是不再自我更新了。

修复被隔离的代理

  1. 先更新该 App。 如果厂商已经修复了这个问题,新版本会重新写入没有该属性的代理文件。
  2. 如果必须手动修复,先检查再信任。 查看它运行的内容:
plutil -p ~/Library/LaunchAgents/some.agent.plist          # look at Program / ProgramArguments
codesign -dv --verbose=2 "/path/to/the/program" 2>&1 | grep -E "Authority|TeamIdentifier"
  1. 只有在确认程序符合预期后,才移除该属性并重新加载代理:
xattr -d com.apple.quarantine ~/Library/LaunchAgents/some.agent.plist
launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/some.agent.plist 2>/dev/null
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/some.agent.plist

不要对你不认识的代理移除隔离属性。通过 LaunchAgents 实现持久化,是恶意软件的经典手法,这项改动的目的正是阻止一个下载来的 .plist 文件悄悄把自己安装进系统。遇到不认识的、被隔离的代理,应该去调查它,而不是重新加载它。我们的登录项与后台 App 指南介绍了如何把一个代理追溯到安装它的 App。

一份后台任务列表,其中部分启动项因隔离标记而被阻止运行

五分钟自查:升级前或升级后都适用

在 Tahoe 上运行以下命令可以预见可能发生的变化,在 macOS 27 上运行则可以确认哪些已经发生:

# 1. How much app data is now guarded by default
ls ~/Library/Containers | wc -l
ls ~/Library/Group\ Containers | wc -l

# 2. Scheduled jobs that may read other apps' data
crontab -l 2>/dev/null
ls ~/Library/LaunchAgents

# 3. Quarantined launch items that will stop loading
for f in ~/Library/LaunchAgents/*.plist /Library/LaunchAgents/*.plist /Library/LaunchDaemons/*.plist; do
  xattr "$f" 2>/dev/null | grep -q com.apple.quarantine && echo "QUARANTINED  $f"
done

# 4. Scripts that read the privacy database directly
grep -rl "TCC.db" ~/bin ~/scripts ~/.local/bin 2>/dev/null

把第 4 步里的文件夹换成你实际存放脚本的位置。对每一个命中的结果,都问一遍 Apple 的变通方法所问的那个问题:这项访问真的有必要吗?

什么情况下不该授予访问权限

这项改动之所以存在,是因为「任何以你身份运行的进程都能读取任意 App 的数据」正是 Mac 信息窃取类恶意软件所依赖的主要机制。在你为了恢复某个功能而授予权限之前,以下几条原则会有帮助:

  • 优先选择最小范围的授权。 在「文件与文件夹」中按 App 单独授权,优先于完全磁盘访问权限;给单个二进制文件授予完全磁盘访问权限,优先于给整个终端 App 授权。
  • 让命令行授权成为临时的。 Apple 自己的措辞是「在需求存续期间」。在日历上设个提醒,到时候把它移除。
  • 对新出现的请求保持警惕。 一个上个月都没理由读取其他 App 数据的 App,这个月却索要完全磁盘访问权限,值得多留意一下。
  • 绝不要从你不信任的网页上粘贴授权命令。 诱导用户运行 Terminal 命令的社会工程学攻击,正是这些保护机制被绕过的方式,我们关于终端粘贴恶意软件警告的文章对此有详细说明。

常见问题排查

即使用 sudo 也出现「Operation not permitted」

问题:sudo ls ~/Library/Containers/…/Data 仍然失败。

解决方法:隐私保护不是 Unix 权限问题,root 同样受其约束。在隐私与安全性中为负责该操作的 App——Terminal,或者启动该命令的任何其他 App——授予访问权限。

launchd 任务失败,但同样的命令在 Terminal 中能正常运行

问题:手动运行某个定时脚本时,它能正常读取另一个 App 的数据,但按计划自动运行时却失败。

解决方法:在 Terminal 中运行时,访问权限归属于 Terminal。而在 launchd 下没有可归属的 App,根据 Apple 的已知问题说明,没有 bundle ID 的进程无法获得按 App 授予的权限。为该任务实际运行的二进制文件授予完全磁盘访问权限,任务不再需要时再移除。

备份工具悄悄跳过了某些 App 数据

问题:备份已经完成,但备份中某个 App 的容器缺失或为空。

解决方法:为备份 App 授予完全磁盘访问权限——这正是它的合理使用场景之一——然后重新运行备份。查看该工具的日志中是否有权限错误;大多数工具即使备份「成功」也会记录这类错误。

升级后某个 App 的功能失效,且没有任何报错

问题:导入、同步或搜索功能没有返回任何结果。

解决方法:到隐私与安全性中查看是否有一条可以允许的条目,并查看厂商的发布说明是否提到 macOS 27 兼容性。如果它想要访问的数据正是 XProtect 守护的那类数据,修复可能需要由开发者那一侧来完成。

后台更新程序停止更新

问题:升级之后,某个 App 的自动更新悄悄停止了。

解决方法:用上文的循环检查它的 LaunchAgent 是否带有隔离属性。先手动更新该 App,这是最可能奏效的修复方式。

FAQ

macOS 27 是否移除了「访问其他 App 数据」的提示?

是的。Apple 的发布说明指出,此类访问「不再提示用户进行授权」,并且「默认被拒绝」。你需要在隐私与安全性设置中进行管理,而不是在事情发生时应答一条提示。

这会影响同一开发者的 App 吗?

不会。这条规则针对的是「其他开发者团队」。由同一个开发者团队签名的 App,仍然可以通过它们的组容器共享数据,这也是一系列相关 App 得以正常协作的原因。

完全磁盘访问权限还够用吗?

根据 Apple 针对命令行已知问题给出的变通方法,答案是够用——完全磁盘访问权限会授予对 App 数据容器的访问权限。XProtect 针对常被针对数据的新限制,是 Apple 描述为独立存在的另一部分,对某些数据可能仍然适用。

为什么我的脚本不能再读取 TCC.db 了?

Apple 的 macOS 27 说明指出,App 不能再直接访问本地 TCC 数据库。请使用系统设置来查看权限;如果你是管理员,则使用设备管理工具的报告功能。

移除 LaunchAgent 的隔离属性安全吗?

只有在你确认了它运行的内容、并确认该程序确实由你预期的开发者签名之后,才安全。移除隔离属性正是恶意软件希望你做的事,这也正是 macOS 27 一开始就停止加载被隔离代理的原因。

结语

macOS 27 这些改动的主题是一致的:属于一个 App 的数据,不再仅仅因为两者都在你的账户下运行就能被另一个 App 获取;一个从互联网下载的文件,也不再仅仅因为落在了正确的文件夹里就能变成后台进程。对大多数人来说,这是一项明确的收益,因为这正是 Mac 信息窃取类恶意软件一直依赖的访问方式。

代价是那些不会被公告出来的故障。脚本、备份工具、导入工具,甚至浏览器的更新程序,都可能悄悄停止工作。运行那份五分钟自查清单,在工具确实需要时按最小范围、临时地授予访问权限;升级之后一旦发现什么东西悄无声息地失效了,先去检查隐私与安全性设置,再考虑其他可能。

相关阅读:macOS 27 无视「Open using Rosetta」:修复缺失的 Intel 插件 · 屏幕录制与完全磁盘访问权限反复弹窗 · 「App 已损坏」与隔离属性 · macOS 27 Golden Gate 首日更新指南