三天的冷却、一天的冷却、五分钟的扫描:信任延迟被内建成默认值

我在上一篇(证明没有撒谎,管道已经易主)里的结论是:在 Mini Shai-Hulud 系列投毒中,真正有效的止损手段不是 SLSA 证明,而是时间本身——官方响应速度、发布冷却、信任延迟。当时这些是社区应急规则(24h/7d 自设规则、靠社区 12 小时发现兜底),不是平台机制。

2026 年 5 月至 7 月,事情变了:GitHub、npm 和 pnpm 把"延迟"做成了一组默认开启的产品机制。这等于给上一轮的判断盖了官方章,但同时也把问题推进了一层——被内建的延迟,各自的语义是什么?它覆盖了哪类攻击,又留下了哪些与延迟无关的洞?

一、两种延迟,不是一种

把 7 月前后的官方公告并排看,会发现"信任延迟"已经被拆成了两种正交的机制,而不是一种。

第一种是无条件时间门,消费者侧。Dependabot 自 2026 年 7 月 14 日起,版本更新默认等待新版本在注册表上存在至少 3 天才开 PR(官方 changelog);安全更新仍然立即开,不延迟。pnpm v11 把 minimumReleaseAge 的默认值设为 1440 分钟(1 天),新发布的版本未满 1 天不会被解析安装(pnpm 官方文档)。这类门不区分好坏,一律延迟,赌的是"社区和扫描器能在窗口内发现恶意版本"。

第二种是条件检测门,注册表侧。npm 自 2026 年 7 月 28 日起在新包公开可用之前先自动扫描,典型延迟约 5 分钟、峰值可达 15 分钟以上,扫描结果决定包是正常发布、暂扣人工审查还是被屏蔽(官方 changelog)。这类门只延迟到扫描完成,赌的是"扫描器当场能检出恶意"。

GitHub 自己的量化支持时间门的赌注。官方博客 The case for a cooldown(7 月 23 日)给出:2025 年 9 月 chalk/debug 事件里,攻击者钓鱼单个维护者凭据后发布的毒版本存活约 2 小时,而涉及的包合计每周下载超 20 亿次;axios、Solana web3.js、ua-parser-js 的投毒版本都在数小时内被拉下;GitHub Advisory Database 在截至 2026 年 5 月的一年里发布了 6,500+ 条 npm 恶意公告(前一年约 6,200 条),即每天约 18 个新恶意包。相比之下,npm 扫描的 5–15 分钟窗口比最快的社区发现还短一个数量级——它不是时间赌注,是检测赌注。

二、默认值分布成了新的安全分界线

这批机制最值得注意的不是"存在",而是"默认开还是关"。

  • pnpm v11:1 天冷却默认开,可设 0 关掉,也可设 10080(1 周)。
  • Dependabot:3 天冷却默认开,只作用于版本更新;可用 cooldown 选项改或关。
  • npm v12(7 月 8 日 GA):默认收紧的是能力性的——allowScripts 默认关(依赖的生命周期脚本不再自动跑)、--allow-git 与 --allow-remote 默认 none(git 依赖和远程 URL 依赖不再解析)(官方 changelog)。但 CLI 本身没有默认的时间冷却。

也就是说,同一个注册表,用哪个客户端决定你是否默认拥有时间保护。pnpm 用户默认被延迟 1 天,npm CLI 用户的"时间保护"只有注册表侧那 5–15 分钟扫描。默认开关现在是一个安全决策,而主流客户端里默认姿态最弱的仍是 npm CLI 本身——虽然 npm v12 在脚本和依赖来源上的收紧是实质性的。

三、no-downgrade 把证明层的洞搬进了安装决策

pnpm 的 trustPolicy: no-downgrade 值得单独说。它的语义是:如果某版本相对该包此前发布版本的信任等级下降(例如以前是可信发布者、现在只有 provenance 或毫无证据),安装被阻止。

这里有一个与我上一篇结论直接接缝的事实:信任等级比较的是发布通道强度(信任发布者 > provenance > 签名 > 无证据),不是内容是否恶意。Mini Shai-Hulud 式攻击恰恰是同级接管——OIDC 令牌被捕获、凭据合法,恶意版本带的是与真品同等甚至更完整的证明。信任等级没有下降,no-downgrade 不会触发。它防的是"凭据从 OIDC 掉到普通 token"这类降级事故,不是被以同等级通道接管。证明层的语义边界(记录发生了什么、不担保本应发生什么)原样被搬进了安装决策,只是换了个名字。

四、冷却只延迟,不裁决

时间门能过滤"短命发布"的主流——GitHub 的数据说大多数恶意版本数小时内被拉下,1–3 天的窗口确实覆盖了 chalk/debug、axios 这类案例。但冷却从不裁决:3 天或 1 天后仍未被发现的恶意版本照常过门,而且攻击者读文档,完全可以发布后等窗口过去再等自动化工具拉取。残余风险正是"活得比窗口久"的那类,以及针对新包名的投毒——pnpm 的 minimumReleaseAge 对新包的第一版同样适用,但对默认无时间门的 npm CLI 用户不适用。

另外两个新博弈面来自 7 月 28 日的公告:dual-use 声明(package.json 里的 contentPolicy 字段 + 包根目录的 DISCLOSURE 文件)让维护者自我声明"我的包有安全相关能力但用途合法"。官方明确声明这不自动放行、会触发更多双用途扫描、由 Trust & Safety 逐例审查——但恶意发布者把 DISCLOSURE 写得冠冕堂皇以显得合规,在原理上是可行的。这是我的推断,目前没有公开实证,不构成已发生的滥用。以及 staged publishing(5 月 21 日进入 CLI v11.15.0,The Register 报道):把发布拆成"自动化提交 staging + 人工 2FA 批准"两步。注意 7 月 8 日的 changelog 明说,带 bypass-2FA 的 granular access token 仍可推到 staging——真正的收缩要到 2027 年 1 月,届时这类 token 失去直接发布能力。这是一次渐进式收权,不是一步到位。

五、判断与观察点

调查没有推翻我上一篇的判断,反而把它具体化了:信任延迟确实被认定有效,并被做成了默认值。但产品化暴露了三个此前不明显的事实:(1) "延迟"已是两种不同赌注,时间门靠社区发现、检测门靠扫描器能力,两者不互相兜底;(2) 默认值的分布把安全姿态重新分配给"你选了哪个工具",这是设计选择不是技术必然;(3) no-downgrade 等机制继承了证明层的同一级接管漏洞,产品化没有绕过它,只是把它写成了配置项。

接下来值得盯的:攻击者是否转向"存活超过冷却窗"的发布策略;npm CLI 是否跟进默认时间门;PyPI、RubyGems 是否出现同类产品化;以及 dual-use 声明是否出现被滥用的实证。GitHub Advisory Database 的公告数量与发现时间分布,也会是检验冷却期实际效果的公开数据。

来源

回复与讨论

留下回复

无需登录或邮箱。昵称可选;勾选保存后,WordPress 会用第一方 Cookie 在下次自动带回。本站不保存评论 IP 或浏览器标识。

每条 2–150 字;匿名每小时最多 5 条,登录用户每小时最多 15 条。

评论者识别当前追踪标识:未建立

↑ 回到顶部