← 返回所有文章
发布于 · 作者 Renaud Deraison

这个权限本来是给备份用的

10 月 2 日,Apple 表示将为 macOS 的完全磁盘访问权限加上新的管控。这个设置原本是为了让备份 App 正常工作,但“随着 AI 代理变得越来越强大、越来越自主,这种级别的访问所带来的风险将大幅增加”。导火索是 Meta 的 Muse:一位记者说它把他的信息数据库同步到了第 187,462 行;另一件是 Patrick Wardle 在 ChatGPT Mac App 中发现的漏洞。编程代理可以从启动它的终端继承同样的访问范围,而它能读到的开发者机密,从来就不在这个权限的保护之下。在 Bromure Agentic Coding 中,代理不是 Mac 上的进程:它运行在一台 Linux VM 里,VM 中只有你共享的文件夹和替身凭据。

Apple 打造完全磁盘访问权限,是为了让备份 App 能读取一切。如今 AI 代理要求同样的访问范围,而在开发者的 Mac 上,它们往往不用开口,就从终端那里拿到了。

10 月 2 日,Apple 在开发者新闻页面上发布了一则简短公告,标题是 Updates to Full Disk Access in macOS。公告解释了这个设置存在的原因:“完全磁盘访问权限在很大程度上绕过了这些管控,以便备份 App 能在 Mac 上正常工作。”接着描述了部分开发者拿它做了什么:“在用户未充分知情和理解的情况下,暴露了他们系统上的一切,包括文件、邮件、信息,甚至浏览历史。”

Apple 将增加管控,让想授予这种访问权限的用户“只能通过非常明确的用户操作”来授予。Apple 也说明了现在采取行动的理由:“随着 AI 代理变得越来越强大、越来越自主,这种级别的访问所带来的风险将大幅增加。”

Apple 没有给出日期,也没有说明已有的授权会如何处理。但这则公告清楚表明了 Apple 怎么看待落到代理手里的完全磁盘访问权限。

两周内的两条新闻

对这则公告的报道, 从 TechCrunch 开始,都把它和两起事件联系在一起。

Muse 与信息数据库。 9 月 19 日,Inc. 专栏作家 Jason Aten 报道,他 Mac 上的 Meta Muse 代理发来一条通知,建议他以刚刚和播客联合主持人的对话为题写一篇专栏。他说自己拒绝了 Muse 访问信息的请求,却发现 Muse 已经把他的信息数据库同步到了第 187,462 行,而 Muse 自己的设置显示完全磁盘访问权限是关闭的。 Meta 对这一说法提出异议。Meta Superintelligence Labs 的 David Singleton 表示,Muse 必须经过“三个独立步骤,包括应用级别的权限和 macOS 内置的系统级保护”才能读取信息,而这些保护“即使 Muse 应用有 bug 也无法绕过”。Muse 自己则告诉 Aten,它一直在同步他的设备通知。

Objective-See Foundation 的 Patrick Wardle 总结了 App 一旦拿到这个权限意味着什么:“任何(非 root 的)文件都可读取,浏览历史、浏览器 Cookie、聊天记录等等。”

ChatGPT 的 Mac App。 同一周,Wired 报道了 Wardle 在 OpenAI macOS 版 ChatGPT App 中发现的漏洞 CVE-2026-100754。这个 App 根据代码签名和进程的父子关系来决定信任哪些本地进程。一个受信任的脚本解释器可以被喂入不受信任的输入,让已经在 Mac 上运行的普通代码混进一条被接受的进程链,进而操控 App 的受信任功能:聊天记录,以及浏览器会话等已连接的集成。OpenAI 在构建版本 26.924.20706 中修复了这个漏洞,该版本自 9 月 25 日起上线。目前没有任何实际被利用的报告。

两条新闻的前提相同。Mac 上的代理以你的身份运行,凡是它能读到的,任何接管这个代理的代码也都能读到。

终端早就同意了

Muse 是通过系统设置申请完全磁盘访问权限的,正如 Apple 的模型所预期。终端里的编程代理什么都不申请,直接沿用终端的授权运行。

macOS 会针对负责的 App 检查隐私权限,对命令行工具而言,就是启动它的那个终端。许多开发者多年前就给了终端、iTerm 或编辑器完全磁盘访问权限,好让 find、rsync 或备份脚本不再弹出询问。从那个窗口启动的每个进程都会继承这份授权。这包括 Claude Code、Codex 和 Gemini CLI,以及 npm install 的每个 postinstall 脚本、它们启动的每个 MCP 服务器,还有每一条被 README 说服而执行的单行命令。

在这种配置下,Apple 列出的文件,代理和代理运行的一切都够得着:

  • ~/Library/Messages/chat.db,也就是 Muse 被指控同步的信息记录
  • ~/Library/Mail,每一个邮箱
  • Safari 的浏览历史和 Cookie,位于 ~/Library/Safari 及其容器中
  • 备忘录、照片图库,以及其他 App 的私有容器

机密从来不在询问弹窗后面

Apple 的改变是对的,它保护了大家认为是隐私的文件。但开发者工作用的凭据放在别处。下面这些路径,既不受完全磁盘访问权限保护,也不受 macOS 任何其他隐私权限保护:

  • ~/.ssh/id_ed25519
  • ~/.aws/credentials 和 ~/.aws/sso/cache/
  • ~/.config/gh/hosts.yml、~/.git-credentials、~/.npmrc、~/.docker/config.json、~/.kube/config
  • 你克隆过的每个项目里的 .env 文件
  • 代理本身的 OAuth 令牌和会话记录

任何以你的用户身份运行的进程都能读取它们,不论有没有完全磁盘访问权限。Apple 的新管控会让一个大权限更难授予。但笔记本上的编程代理本来就不需要这个权限,就能拿到让攻击者推送到你的仓库、或打开你 AWS 账户的文件。针对编程代理的信息窃取程序已经在收集这些文件:访问令牌和刷新令牌、MCP 配置、提示历史。

在检查哪些 App 拥有完全磁盘访问权限之前,先看看代理的电脑里有什么。

笔记本:代理以你的身份运行终端(已授予完全磁盘访问权限)claude / codex / gemini+ postinstall、MCP 服务器、单行命令受完全磁盘访问权限保护(继承)~/Library/Messages/chat.db~/Library/MailSafari 历史与 Cookie毫无保护(任何进程)~/.ssh/id_ed25519 ~/.aws/credentials~/.config/gh/hosts.yml ~/.npmrc每个 .env OAuth 令牌Bromure:代理运行在 VM 里VM(Ubuntu)claude / codex / grok + 子进程/home/ubuntu(自有)~/your-project(共享)GH_TOKEN=ghp_… sk-ant-api03-brm-…(假)没有 ~/Library、信息、邮件Mac(VM 之外)信息、邮件、Safari、其余文件加密保险库:令牌、AWS、SSH 密钥代理服务器:追踪、防火墙、确认替身发错主机 → 451,VM 暂停真凭据只在所属主机换上
在笔记本上,代理以你的身份运行。拥有完全磁盘访问权限的终端会把授权传给代理,以及代理启动的一切,于是信息、邮件和 Safari 的数据都被打开。放在 dotfiles 里的开发者凭据则根本不需要授权。在 Bromure 中,代理运行在一台 Linux VM 里,只看得到你共享的文件夹和替身凭据;真正的凭据留在 Mac 上,由代理服务器使用。

在 Bromure 中,代理不是 Mac 上的进程

Bromure Agentic Coding 在 Apple Virtualization.framework 之下的 Ubuntu VM 中运行每台机器的代理。Claude Code、Codex、Grok 等都是 Linux 内核上的 Linux 进程。它们从不打开 Mac 文件系统上的文件,所以 macOS 的隐私权限对它们不适用。没有可以继承的授权,也没有会把权限泄漏给代理的终端,因为你在 Bromure 中看到的终端连接的是 VM,而不是你 Mac 的 shell。

VM 看得到的东西,只有短短一张清单:

  • 它自己的系统磁盘,是一份已签名 Ubuntu 镜像的写时复制(copy-on-write)克隆。
  • 它自己的主目录 /home/ubuntu,放在一个私有的磁盘镜像上。
  • 你和这台机器共享的文件夹,最多八个,各自以名称挂载在主目录下。如果你共享 ~/code/payments,代理看到的是 ~/payments。它看不到 ~/code,也永远看不到 ~/Library。
  • 每次启动的一个小型配置共享,只读,存放代理服务器设置和替身凭据。

chat.db 不在这张清单上,邮件和 Safari 的浏览历史也不在。一个像 Muse 那样的同步任务,或是一个遭到提示注入、被要求“把我最近的信息整理成摘要作为上下文”的代理,只会发现 ~/Library/Messages 根本不存在。VM 里没有任何路径通往那里。

开发者机密都是替身

这样就覆盖了 Apple 的清单。Bromure 也覆盖了 Apple 公告略过的那张清单:dotfiles。

真正的凭据加密后留在 Mac 上。VM 拿到的是格式正确的替身:GH_TOKEN 是 ghp_ 加上 36 个 GitHub 会拒绝的字符,ANTHROPIC_API_KEY 是 sk-ant-api03-brm-…,而 ~/.git-credentials、~/.docker/config.json 和 ~/.kube/config 里放的都是假的。Mac 上的代理服务器会在请求离开 VM 之后才填入真正的值,而且只在请求要发往该凭据所属的主机时才这么做。用手册的话来说:“VM 内的任何文件、环境变量或进程,都不会包含真正的 API 密钥、OAuth 令牌、AWS 密钥或 SSH 私钥。”

有两个细节回应了 Apple 对大范围授权的担忧:

  • AWS 导入只要求 Mac 上的一个文件夹。 导入你的 AWS 配置文件时,Bromure 只针对 ~/.aws 请求一份 security-scoped 授权。这个文件夹在 Mac 上读取,从不挂载进 VM。这正是 Apple 公告所要求的那种范围窄、意图明确的授权,而且它给的是宿主 App,从来不是代理。
  • SSH 密钥留在 Mac 上。 VM 的 SSH_AUTH_SOCK 是一座通往 Mac 上 SSH agent 的桥。客户机可以请求签名,但私钥的字节从不进入 VM。你 macOS 登录会话的 ssh-agent 也从不暴露给它。

当 Claude Code 通过 Bromure 登录时,OAuth 流程在你 Mac 的浏览器里进行,令牌存放在 Mac 上。VM 的 ~/.claude 里没有任何真正的令牌。而那正是针对编程代理的信息窃取程序要找的文件。

浏览器也有自己的磁盘

Apple 提到了浏览历史,Wardle 提到了 Cookie。Bromure 中的代理有一个浏览器,是代理通过内置 browser MCP 服务器操控的完整 Chromium。它运行在第二台用完即弃的 VM 里,和代理的机器、和你的 Mac 都是分开的。默认情况下,它的磁盘是一份临时克隆,浏览器关闭时就会删除,所以 Cookie、登录状态和浏览历史都会随之消失。它无法访问 Safari 的浏览历史或你桌面版 Chrome 的配置文件,因为那些都在 Mac 上。

一切外流都要经过 Mac

假设代理真的从你共享的项目文件夹里收集到值得偷的东西。它只有一条出路。VM 的虚拟交换机会把每个网络连接导向 Mac 上的代理服务器,而客户机无法关掉这个机制。

  • 在默认的追踪级别下,每个请求都会写进 Mac 上的加密追踪记录,与模型的往来内容会被拆解成代理发出的工具调用和 shell 命令。Trace Inspector 会在 POST 发往陌生主机的当下就把它显示出来。
  • 机器的出站防火墙在 Mac 上执行,可以只允许项目需要的主机,其余一律丢弃。
  • 如果载荷里带着某个替身凭据,代理服务器会发现一个凭据正被发往不属于它的主机。它会返回 HTTP 451、暂停 VM,并在 Mac 上弹出警报:This environment may have been compromised。

本地 IPC 手法需要 Mac 上的进程

CVE-2026-100754 的前提是“已经在 Mac 上运行的非特权代码”能触及 ChatGPT App 的本地信任通道。在笔记本上,以你的身份运行的代码,最活跃的来源往往就是编程代理:它安装的依赖、它运行的脚本、它下载的工具。在 Bromure 中,这些代码都在 Linux 客户机里运行。Mac 的 XPC 服务、Unix socket,以及背后的桌面 App,都在另一个内核里。VM 中的恶意 postinstall 脚本无法加入 Mac 上的进程链。

一项工作一台机器

共享文件夹决定了代理能看到多少。每台 Bromure 机器都有自己的文件夹列表、自己的凭据和自己的主目录,所以好习惯很容易养成:

  1. 每个项目都用一台专属的机器,只共享那个项目的文件夹。
  2. 只给机器它的项目用得到的凭据。用来试新 MCP 服务器和代理插件的实验机器,一个都不给。
  3. 保持 Prompt before write 开启,这是新机器针对 GitHub、云服务商、镜像仓库、Kubernetes 和数据库的默认值。推送和删除会停下来,等待一个显示确切操作内容的 macOS 对话框。
  4. 永远不要共享你的主目录。代理不需要它。

每次机器启动也会为主目录创建一个写时复制的检查点,所以 Rewind home… 可以找回代理在那里删掉的东西。

没有可继承的 macOS 权限

代理是 VM 里的 Linux 进程。它从不在你终端的完全磁盘访问权限之下运行,信息、邮件和 Safari 的数据也不在它的磁盘上。

只有你挑选的文件夹

每台机器只看得到自己的主目录,以及你按名称共享的最多八个文件夹。你 Mac 的其余部分,包括 ~/Library,都不在那里。

dotfiles 里都是假的

Git、云、镜像仓库和模型的凭据都是替身。SSH 私钥从不进入 VM。Mac 上的代理服务器在传输途中填入真正的值。

每条出路都有记录

网络流量经过主机上的代理服务器:被追踪、被出站防火墙过滤,替身一旦发往错误的主机,就连同 VM 一起暂停拦下。

给代理一台自己的电脑

Apple 的公告,是一家操作系统厂商告诉开发者:为备份软件设计的权限,不该交给自主代理。Apple 说得对。它的解法是更清楚的询问弹窗,而用户仍然得在一台存放着自己一切的 Mac 上,为每个 App 做出正确的选择。

Bromure 给代理一台自己的电脑。上面有你共享的项目,以及只有在你 Mac 上的代理服务器换上真货时才有效的密钥。等 Apple 的新对话框推出时,你的编程代理不会是弹出它的 App 之一。