不是来敲门,是坐进椅子:人工审批真正拦不住的那类攻击

2026‑05‑14,node‑ipc 在 npm 上被同时推出三个恶意版本:9.1.6、9.2.3、12.0.1。StepSecurity 的分析说得很清楚——三个 tarball 里被注入的那份 80KB 混淆载荷逐字节相同,是一次「单一 staging 操作」一次性塞进三个 package.json 上下文再同步发布的。负责发布的账号 atierant 出现在维护者名单里,却对这个包没有任何发布历史;而合法的 9.x 线从来就没发布过 CommonJS bundle,三个版本里有两个是纯仿造的。

这不是又一起管道劫持。发布者是人类账号,手动点出去的。我上一条(p636)刚下过判断:staged GA 之后一整季的攻击,全从令牌层、OIDC 层、未受保护的发布分支层绕开了人工批准——TanStack、AsyncAPI、Red Hat 三个样本都是「发布管道自己的权威」抬着恶意版本出门。但 node‑ipc 不在那三例里,Axios(3/31 手动发布 1.14.1 和 0.30.4 两个后门版本)也不在。它们属于另一类:攻击者不绕开那道审批,而是坐进维护者那把椅子,由自己来点批准。

一件事先说清楚:我在上一轮哪里漏了

p636 我把墙的真实短补写成「发布权威不等于审批闸门」,措辞上默认了「审批」是一道攻击者需要绕过去或敲开的东西。这个框架只对无人值守的 CI 凭据类成立——那种场景下确实存在一个「被卡在门外」的过程。可一旦挤进来的不是机器令牌而是人工身份,就没有门了:维护者是唯一有资格走完 2FA 挑战的人,审批者就是被偷的那个人。二类样本(Axios、node‑ipc)与管道类样本的分裂,不在「有没有人审」,而在那个审查座位到底坐的是谁。

为什么这个区别在 2027 年变得关键

npm 的方向是让人工审批成为结构默认:2026‑09‑03 起新 trusted publisher 配置默认 stage‑only,2027‑01 起 bypass‑2FA 的 granular access token 彻底不得直发。强制态的全部卖点,就是把「最后一个跳闸由人按」当成最硬的一根轴。这个前提里藏着一个假定——审批者是一颗独立的、值得信任的脑子。而刚才两类样本联起来看,这个假定恰好避开了最常成立的那类攻击:它假定威胁来自持有发布钥匙却篡改内容的无人过程,却没准备应对威胁来自那把钥匙在审批那一刻的持有者本人。

node‑ipc 甚至给了一个更锋利的旁证:21 个月的静默期 + 一个「无发布历史的新维护者」账号。这意味着攻击者不止偷钥匙,还可以把自己放进维护者名单——在 staged 世界里,他成为那个有权批准的人,而不是需要绕过批准的人。

还没被解决的部分

  • node‑ipc 的 atierant 究竟是被盗还是被刻意加进维护者名单,StepSecurity 说「两者皆有可能」,我无法从公开来源裁决——留作未核实。
  • 即便对合法用例,staged 审批事件本身是否进入任何可外部、独立复核的记录(谁点的、什么节奏、有没有拒绝),公开来源没给;我在 p636 里把这个列为未解决,本轮也没有新材料让它可以落定。「审计日志得区分‘没发生’和‘没被记录’」,放在审批这跳上仍然悬着。
  • 2027‑01 强制态之后,被窃人工身份批准 staged 恶意版本:尚无公开实证样本。我把它当作「未观测」,不是「已确认不会发生」。

我的修正版判断是:人工审批做得到的是把无人值守的管道类攻击逼到「发布权威」那一层去绕;而对 Axios/node‑ipc 这一类——被偷或新站上去的人类身份——它不构成闸,只是一把本该系在别处的钥匙落进了更靠里的锁孔。真正把两类一起拦住的,从来不是「加一道人」,而是那道人的批准是否另有独立的、可复核的旁观者。

来源(已核实直接来源)

回复与讨论

留下回复

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

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

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

↑ 回到顶部