正在刊行长文 · Essay
2026-06-12所有内容
随机比特 · Random Bits

Homebrew 6.0 升级前,先跑这三条命令

2026-06-12AI Engineering / Systemsrbits.uk
Homebrew 6.0 升级前,先跑这三条命令

Homebrew 6.0 升级前,先跑这三条命令

Homebrew 6.0 昨天发布了。这个大版本里真正会改变你日常操作的,是第三方 tap 的信任模型:以前 tap 完代码就能跑,6.0 起不显式信任就不求值。只用官方源的人直接升级,无感;装过第三方 tap、或者 CI 里跑 brew 的,有几种场景会直接断——升级前值得花三分钟做一次自查。

信任检查挪到了"求值之前"

formula 和 cask 本质是 Ruby 代码。brew install 装一个包时,Homebrew 先加载对应的 .rb 文件——这一步是真正的代码求值:文件顶层写了什么就执行什么,没有沙盒,权限就是你当前用户的权限。而且求值不只发生在 install——info、upgrade 这些命令同样要加载 formula。

5.x 及以前,这条链路上唯一的确认点是你敲 brew tap 的那一刻。之后每次 brew update 从这个 tap 的 remote 拉新 commit,新代码不需要任何确认就获得同样的执行资格——你实际信任的是这个 remote 的全部未来提交。口子还更宽:brew install user/repo/tool 会替你把没 tap 过的源自动拉下来(auto-tap),连那一次确认都省了。

6.0 把检查点前移到求值之前:未信任的 tap,它的 formula/cask 在被加载前就拦下,Ruby 根本不执行;对未信任 tap 的 auto-tap 停用;官方 tap 默认信任。有一条例外路径:全限定写法 brew install user/repo/tool 仍然可用——Homebrew 会在安装前对这个具体条目做信任处理,相当于你点名了要装什么,它按条目级别给信任。配套的操作面:brew trust 显式信任一个 tap(支持按 remote URL 信任),brew tap-info 多了 trusted 字段,Brewfile 的 tap 条目支持 trusted: 选项、brew bundle dump 会把自定义 remote 的 tap 记录成 trusted。

01-tap-trust-flow

有一个容易被忽略的细节:信任名单是 pin 到 remote URL 的,不是 tap 名字。tap 的 remote 被换过——比如国内常见的指到镜像、或者指到自己的 fork——信任要按实际 URL 算。

直接动机写在发布公告里:6.0 同时披露并修复了三个安全漏洞——POST 下载策略绕过 HTTPS 重定向保护、macOS .pkg 安装器经 Git hooks 拿到 root 执行、/var/tmp 下的 plist 让本地攻击者可以接管 Homebrew 属主。三个洞的共同点,都是代码在没人确认的环节跑了。

升级前自查:三条命令

# 1. 列出所有非官方 tap——升级后每一个都需要显式信任
brew tap | grep -v '^homebrew/'

# 2. 这些 tap 装了哪些包——这就是会受影响的具体清单
brew list --full-name | grep '/'

# 3. 逐个看 tap 的 remote 指向哪——信任 pin 在 remote URL 上,按实际 URL 确认
brew tap-info <user/repo>

升级后,对自查出来的每个 tap:先看 remote 是不是你认识的来源,确认后 brew trust <user/repo>,再用 brew tap-info 的 trusted 字段核对状态。

CI 不要走交互式处理。我的建议是把信任写进 Brewfile(tap 条目加 trusted: 选项),让信任决策进 code review——比散落在某台 runner 镜像里的几条 brew trust 可追溯得多。

再跑一下 brew developer。输出 on 的注意:6.0 起 ask mode 对 developer 默认开启,brew install / brew upgrade 会先列出依赖摘要、等一次按键确认,无人值守脚本会卡在这一步。普通用户不受这条影响。

哪些场景会断:逐个对照

你的情况 升级后会发生什么 要做的事
只用 homebrew/core、homebrew/cask 无感,官方 tap 默认信任 直接升
装过第三方 tap 的包 tap 未信任前,相关包不可装不可升 核对 remote 后 brew trust
CI 里 brew install 第三方 tap 的包 断:没有人做信任确认 Brewfile 标 trusted: 或镜像构建时预信任
脚本里用短名装第三方 tap 的包(已 tap 未信任) 受影响:tap 求值被拦 显式 brew trust;全限定 brew install user/repo/tool 是例外路径,但 CI 更稳的做法是 Brewfile 写明 trusted:
tap remote 指过镜像 / fork 信任按 remote URL 算,不按名字 brew tap-info 逐个核对,按实际 URL 信任
developer mode 开着的无人值守环境 install/upgrade 停下来等确认 评估关掉 developer mode,或在脚本里处理确认
Intel Mac 2026 年 9 月起 Tier 3:无 CI、无新 bottle,装包退回源码编译;2027 年 9 月完全停止支持 一年内规划迁移,别拖到只剩源码编译的阶段
GitHub Actions 还在引用 Homebrew 的 @master 官方 Actions 已开始警告 引用迁到 @main

顺手的收益也有一项:内部 JSON API 这次转正成默认——所有元数据合并成单次下载,brew update 更快、联网更少。之前手动设过 HOMEBREW_USE_INTERNAL_API 的可以删了,这个变量已经废弃。

tap 里的代码,仍然以你的权限执行

信任模型改了,但有一件事没变:tap 里的 Ruby 依然以你的用户权限、不进沙盒地执行。6.0 改的只是谁、在什么时候确认这份信任——从"tap 那一刻起永久有效",变成"显式授予、绑定 remote"。

所以别把 brew trust 当成升级路上多出来的一步麻烦:它就是你过去一直在隐式做的那个决定,现在摆到了台面上。敲下去之前花十秒看一眼 remote URL——这十秒,就是这个大版本给你的全部新增安全。

随机比特公众号二维码
公众号 · 随机比特
从 AI 工具热闹里拆工程真相

写边界、控制面、上下文、成本与安全。