升级到 macOS 15 Sequoia 之后,许多 Mac 用户每天打开 Chrome、Arc 或 Brave,都要迎面撞上同一个系统弹窗,询问是否允许应用查找本地网络上的设备。哪怕你昨天刚点过拒绝,今天重启浏览器,它依然像失忆一样准时出现。开发者 johncassil 忍无可忍,在 GitHub 上扔出了一个单文件、零依赖的 Swift 开源工具 dontallow。它的逻辑简单粗暴,专门替你在 0.25 秒内按下不允许按钮。

一个连 Xcode 都不需要、只靠 Apple Command Line Tools 就能编译的小脚本,迅速在极客圈传开。表象上看,这只是一个帮人关掉烦人弹窗的自动化工具;往深处扒,它恰好刺中了苹果将 iOS 隐私模型硬搬到桌面端时留下的架构盲区。

0.25 秒的防御与失忆的权限表

先把 dontallow 的底牌亮清楚。它不修改系统文件,也不关闭系统级保护,而是通过监听系统进程 UserNotificationCenter 的窗口创建事件来干活。平时它在后台休眠,空闲时 CPU 占用为零;一旦捕捉到本地网络权限弹窗,核对不在白名单内,就会调用辅助功能(Accessibility)接口直接触发拒绝按钮,如果接口被拒就降级为合成鼠标点击。

应用热更新改变临时路径,触发系统无限重复弹窗(示意图)
应用热更新改变临时路径,触发系统无限重复弹窗(示意图)

它还顺手提供了一个 dontallow rules 命令,专门用来解码 macOS 内部的本地网络规则库,把系统设置里那些指向虚无的僵尸条目扒出来示众。

为什么本该只问一次的权限会变成每日打卡?病根出在传统桌面软件的更新机制与 macOS 权限记忆逻辑的错位上。

  • Chromium 系浏览器的热更新自复制:Chrome、Edge、Brave、Island、Arc 等浏览器在启动时,会把自己的应用包复制到一个随机的临时文件夹里,以此保证就地热更新期间代码签名不断裂。但 dontallow 作者观察到,macOS 把本地网络权限决策死死绑在了这个随机路径上。下一次启动,临时路径变了,系统就当它是全新应用,系统设置的隐私列表里随之塞满了一排排重复的 Google Chrome.app 孤儿条目。
  • 多版本目录与连坐机制.任何把软件安装在 .../versions/1.2.3/ 这类版本化路径下的开发工具,每更新一次就会喜提一行新记录。更荒唐的是系统的归因逻辑,后台守护进程发起的网络请求,往往被系统按头算在某个根本没运行的宿主应用头上,凭空跳出弹窗。
Chromium 热更新如何击穿 macOS 权限记忆 1. 浏览器启动 复制包至随机临时目录 2. 触发局域网请求 系统将决策绑定该路径 3. 再次启动或更新 旧临时目录失效被弃用 4. 判定为全新应用 弹窗重现且堆积孤儿行 注:苹果 TN3179 文档称按代码签名识别,但多版本共存与临时路径在工程现实中直接导致设置列表崩坏。

对于一台普通 Mac 来说,除了打印机工具、媒体服务器或局域网扫描软件,绝大多数应用根本不需要碰本地网络。真正要用时,用户也可以通过 dontallow pause 10m 暂停拦截,或者写进白名单放行。


官方文档与工程现实的对质

如果去翻苹果官方的技术文档,会发现一处耐人寻味的口径打架。

为规整沙盒设计的权限机制,接不住复杂的桌面软件生态(示意图)
为规整沙盒设计的权限机制,接不住复杂的桌面软件生态(示意图)

苹果在 2026 年 2 月 17 日更新的官方技术文档 TN3179 中明确写道,macOS 使用代码签名(Code Signature)来识别程序的本地网络权限,只有未签名或 ad hoc 签名的构建才可能无法跨版本可靠追踪。按苹果的设计理想,只要 Chrome 的签名没变,跑在哪个临时文件夹里都该被认出来。

但现实给了这套理论一记耳光。同样在 TN3179 这份文档里,苹果不得不退后半步,承认系统中安装同一应用的多个版本会导致系统设置出现预期外的行为。在 Apple 开发者论坛的 844209 号线程里,甚至有开发者报告系统设置里的开关明明显示为允许,Chrome 的本地网络访问依然失败,而苹果 DTS 工程师对此只能引导提交反馈,拿不出通用的修复方案。

纸面上的签名追踪有多完美,设置列表里的僵尸条目就有多讽刺。

macOS Sequoia 试图把 iOS 那套严丝合缝的本地网络隐私权限照搬到桌面端。但 iOS 应用活在沙盒里,统一由 App Store 分发和更新,生命周期极其规整;而 Mac 桌面生态经历了数十年演化,到处是自更新脚本、多版本共存和后台代理进程。当操作系统的安全管控粒度强行变细,底层追踪机制却接不住传统桌面软件的复杂形态时,安全防线就退化成了制造警报疲劳的噪音源。

运维死角逼出的安全悖论

更让企业 IT 管理员头疼的是,这块权限目前处于三不管地带。

用敞开金库大门的代价,去修补一扇破洞的纱窗
用敞开金库大门的代价,去修补一扇破洞的纱窗

平时用来重置 macOS 权限的命令行利器 tccutil reset,根本管不到本地网络权限,因为它有自己独立的一套规则存储库。而在企业级设备管理上,苹果的 TN3179 文档也亲口证实,管理员目前无法通过 MDM(移动设备管理)配置本地网络隐私权限。

这意味着管理着上千台 Mac 的企业运维人员,既不能提前帮员工静默拒绝,也没法在列表变脏后一键清空。被逼到墙角的管理员如果想用 dontallow 解围,就得走一条极其拧巴的野路子,用开发者 ID 给 dontallow 签名,再通过 MDM 下发 PPPC(隐私偏好策略控制)配置文件,批量授予这个第三方脚本辅助功能权限。

macOS 本地网络权限的官方设计理想与现实运维困境 官方设计理想(TN3179 规范) • 依赖代码签名跨版本精准识别应用 • 首次询问后永久记住用户授权决定 • 拦截未经授权的局域网设备扫描 • 沿用沙盒时代的洁净应用生命周期 桌面工程现实(用户与运维处境) • 临时目录与多版本路径导致列表崩坏 • tccutil 无法重置,MDM 无配置接口 • 被迫下发高危辅助功能权限模拟点击 • 工具自身未签名时升级也会丢失权限

这构成了整件事里最荒诞的安全悖论。

本地网络权限本来只是为了防止应用偷瞄局域网里的打印机或电视;但为了关掉它失控的弹窗,用户和企业却不得不把系统的辅助功能权限交出去。要知道,辅助功能权限拥有读取屏幕内容和模拟点击的极高特权。用打开金库大门的代价,去修补一扇关不严实的纱窗,这笔安全账怎么算都是倒挂的。

  • 风险.使用辅助功能 API 监听系统 UI 并非毫无隐患。此前在知名窗口管理工具 yabai 的 issue #439 中,就出现过 AXObserverAddNotification 遇到 kAXErrorCannotComplete 错误后无限重试、直接把 CPU 跑满的先例。更黑色幽默的是,因为 dontallow 目前还没有绑上付费的 Developer ID 签名,每次用户通过 brew upgrade 升级它时,它自己也会因为签名改变而丢掉辅助功能权限,得手动去设置里删掉重加一回。

《老子》里讲,法令滋彰,盗贼多有。操作系统的权限条文越写越密,如果配套的清理工具、签名追踪和 MDM 接口跟不上,多出来的规矩非但不能带来安全,反而会逼着开发者和运维人员用更激进的自动化外挂去对抗系统。

目前 dontallow 只支持英文界面的 macOS(匹配了英文弹窗文本与按钮标题),已在 Intel 芯片及 macOS 26.6 测试环境中跑通。在苹果真正修好路径与签名的追踪冲突、并把 MDM 载荷补齐之前,那个本不该存在的弹窗,还得靠这 0.25 秒的机械点击来替苹果擦屁股。