题记与说明
课题:软件供应链攻击链拆解:依赖混淆、恶意包、维护者账号被盗与构建系统投毒
报告类型:横纵综合报告(最终稿——已按独立审读意见逐条修订)
成文日期:2026-10-31(初稿);2026-10-31(修订为最终稿)
输入材料:本文由同课题两份章节稿综合而成——纵轴稿(parts/2026-10-31-软件供应链攻击-vertical.md,基于当日 16 组关键词的 WebSearch 调研)与横轴稿(parts/2026-10-31-软件供应链攻击链拆解-依赖混淆-恶意包-维护者账号被盗-构建系统投毒-horizontal.md,基于 WebFetch 直接抓取 + WebSearch 摘要 + 既有知识三级标注的调研)。两稿之间的事实口径差异(事件日期、包数统计、来源层级、分类归属)已按保守口径合并,并在附录 A 逐条记录消解方式。
修订说明:最终稿按 8 条独立审读意见逐条修订(2026-10-31):① 统一 2.4.2 矩阵解读与 3.1 判断二的 A+E/A+E+C 口径;② 微软 2026-05 披露包数按保守口径统一为 33(45 的更新口径检索未见独立来源,见附录 A 第 4 条);③ "CVE/SCA 企业采购最多"降格为判断性表述(未检索到采购占比统计);④ XZ Utils 补"维护者接管×构建产物投毒"跨链归属说明;⑤ 为 @redhat-cloud-services、Unit 42 威胁图景、keyv/ChainDrop、OMB M-26-05、npm 2027 封禁口径、Socket 融资补充来源链接,无来源事实显式标注"既有知识";⑥ 判断三"四起事件/3 个月落地"改为与正文一致的口径;⑦ 修正 npmjs.help 域名表述、SLSA v0.1、刷量识破等病句;⑧ 补附录 B 术语表、时间线类别注、2.5 第 5 条性质注;附录 A 与附录 B 构成附录块,参考来源保持为全文最后一节。
证据边界:初稿写作时未做新的联网检索,事实继承自上述两份章节稿;最终稿修订时为落实审读意见做了少量补充检索,新增来源在正文与"参考来源"末组中以链接标注(主要涉及 @redhat-cloud-services、Unit 42 威胁图景、keyv/ChainDrop、OMB M-26-05、npm 2027 封禁口径、Socket 融资),其余事实仍继承初稿的来源层级,个别无来源事实已显式标注"既有知识"。每条关键事实保留其检索所得的原始来源链接,读者应以所引链接为准。
TL;DR
软件供应链攻击的杠杆始终指向"被信任的自动化":从 Thompson 编译器后门,到 XcodeGhost、event-stream、SolarWinds、XZ Utils,再到 2025 年 Shai-Hulud 自复制蠕虫,攻击面从代码迁移到身份、CI/CD 乃至 AI 工具链。四条攻击链性格迥异:依赖混淆成本最低,恶意包靠数量取胜(2025 年新增 45 万+),账号被盗单点失守即全下游沦陷,构建投毒最难检测且潜伏最深。近两年的关键变化是四链融合为"账号×恶意包×构建"复合体,拆链研究从分类学变为断链点定位学。防御侧没有任何单一路线有效:企业采购中最受倚重的 CVE/SCA(业界普遍观察,属判断性表述而非采购统计)对投毒整体盲视,最优组合是"来源证明+入口与运行时管控+行为分析";行业范式正从声誉信任迁移到密码学可证明。
一、纵轴:发展脉络(1984–2026)
1.1 概念锚点:这个课题"诞生"于何处
软件供应链攻击作为一个技术概念,公认的思想起点是 Ken Thompson 1984 年的图灵奖演讲《Reflections on Trusting Trust》:他在 C 编译器中植入自我复制的后门,证明即使逐行审计源码也无法信任编译产物——这是"构建系统投毒"的理论原型(ACM 原文 DOI)。
但它作为真实世界的大规模威胁被行业正视,通常从三个标志性节点算起:
- 2015 年 XcodeGhost:攻击者把带毒的苹果 Xcode 开发工具(安装包约 4GB,官方源在中国下载极慢)散布到中文网盘,开发者用它编译出超过 4000 款含恶意代码的 iOS 应用并通过 App Store 审核,受害应用包括微信、滴滴打车等,波及上亿用户(Threatpost)。
- 2018 年 npm 生态连环事件:
event-stream后门与eslint-scope维护者令牌失窃,让"开源注册表也能被武器化"成为开发者社区的主流认知。 - 2020 年 12 月 SolarWinds SUNBURST:国家级攻击者攻入 Orion 构建系统,在官方签名更新中投放后门,供应链攻击自此进入国家级威胁清单(FireEye 首次披露、SolarWinds 调查、CISA AA20-352A)。
本课题覆盖的四条攻击链——依赖混淆、恶意包投毒、维护者账号被盗、构建系统投毒——在 2021 年前后基本全部"实名化",并在之后五年里持续演化、互相叠加。
1.2 阶段一(1984–2015):理论奠基与第一次实战
- 1984:Thompson《Reflections on Trusting Trust》提出编译器级后门,奠定"信任链"问题的理论基础。
- 2010 前后:npm(2010)、PyPI、RubyGems、Maven Central、crates.io(2014)等公共包注册中心进入繁荣期,"数百万行代码、绝大多数来自第三方依赖"成为现代软件的默认形态,攻击面随之形成。
- 2015-09:XcodeGhost 事件爆发——首次证明"污染开发工具 > 污染单个应用"的杠杆效应;攻击者身份至今未完全确认。
这一阶段的驱动因素极具代表性:基础设施(官方下载源)在部分地区体验差 → 开发者自发寻找镜像 → 攻击者恰好填上这个"信任真空"。此后每一个阶段,驱动因素几乎都是同一句反问:开发者最信任什么,就投毒什么。
1.3 阶段二(2016–2019):注册表生态的"地震期"——恶意包与账号盗取登场
- 2016-03 left-pad 事件(非攻击,但定义了生态脆弱性):开发者 Azer Koçulu 因与 Kik 公司的包名纠纷一怒之下下架全部 273 个包,11 行代码的
left-pad被删后 Babel、React、Webpack 等数以千计的项目构建全线崩溃,npm 被迫手动恢复(The New Stack 回顾)。它暴露了"微型传递依赖 + 无缓存实时拉取"的结构性风险,是后来一切依赖治理讨论的原点。 - 2017-07/08 crossenv 事件:攻击者 "hacktask" 一次性发布约 38 个仿冒热门包名的 typosquatting 包(如
crossenv仿cross-env),借 postinstall 脚本窃取环境变量与凭据,npm 删除恶意包并吊销泄露令牌——恶意包(typosquatting + 安装钩子)成为可复制的攻击模板(npm 官方博客)。 - 2018-07-12 eslint-scope 事件:ESLint 维护者的 npm 账号被盗,攻击者发布带毒版本,postinstall 脚本专门窃取
.npmrc里的 npm 令牌并回传到npmjs.evilpackage.net——"偷一个令牌→发更多毒包"的自增强攻击链首次亮相;npm 估计约 4500 个账号的令牌可能泄露,吊销了截至当日的全部令牌(ESLint 官方事后分析)。 - 2018-11 event-stream 事件:原作者 Dominic Tarr 因精力不足,把广受欢迎的
event-stream移交给主动"热心贡献"的用户right9ctrl;后者加入混淆依赖flatmap-stream,精准瞄准 Copay/BitPay 比特币钱包,解密并外传钱包私钥,社区成员逐行反混淆才发现真相(事件取证)。这是"维护者的社会工程接管"的经典案例——六年后 XZ Utils 的 Jia Tan 是它的"耐心的完全体"。 - 2019-01 PEAR 事件:PHP 最老牌包管理器 PEAR 的官网被入侵,
go-pear.phar安装器被替换为带自毁机制的后门,攻击者身份至今成谜(The Hacker News、Help Net Security)。
此阶段的结构性矛盾浮出水面:开源维护"单点人格化"(一个邮箱、一个令牌 = 发布权)叠加依赖图的无信任传递;npm 开始收紧下架政策、推动令牌与 2FA 改进,但整体仍是"事后灭火"。攻击端也从 opportunistic 的勒索/挖矿转向金融定向攻击。
1.4 阶段三(2020–2021):国家级警报与"依赖混淆"的命名之年
这是本课题最重要的分水岭:"软件供应链安全"从开发者话题升级为国家议题,四条攻击链全部得到正式命名或定性。
- 2020-03/04:GitHub 收购 npm(官宣),注册表的资本与治理格局改变;同年 8 月 Linux Foundation 联合谷歌等成立 OpenSSF(开源安全基金会)。
- 2020-12 SolarWinds SUNBURST:APT 级攻击者(普遍归因至俄罗斯背景的 APT29/Cozy Bear,官方未完全定论)在 Orion 的构建服务器上植入 SUNSPOT 恶意模块,使每次官方构建自动注入 SUNBURST 后门,随合法数字签名更新分发,约 1.8 万客户下载、上百个高价值目标被渗透。"构建系统投毒"自此有了教科书案例(FireEye 披露、SolarWinds 调查、CISA AA20-352A)。
- 2021-02 Alex Birsan 公开"依赖混淆(Dependency Confusion)":研究者向 npm/PyPI/RubyGems 上传与 35+ 家大厂(Apple、Microsoft、PayPal、Shopify、Netflix、Tesla、Uber 等)内部私有包同名的公共包,利用包管理器"取更高版本号"的默认行为,让企业 CI 主动执行他的代码,累计获得超过 13 万美元赏金(Birsan 原文)。这是本课题第一条攻击链的"命名时刻",此后各生态的内部源(npm scope、Artifacts upstream、pip extra-index 行为)全面整改。
- 2021-04 Codecov 事件:CI 覆盖率工具的 bash 上传脚本被篡改约两个月未被发现,窃取 CI 环境变量;哈希算法泄露导致 HashiCorp 的 GCS 令牌失窃、代码签名二进制 bucket 被访问(Codecov 官方披露、事后分析)——CI/CD 环境成为供应链攻击的"第二战场"。
- 2021-05-12 美国行政令 EO 14028:SolarWinds 的直接产物,要求 NIST 建立供应链安全指南(SSDF)、商务部发布 SBOM 最小要素,"证明你的软件是怎么造出来的"成为合规命题(NIST EO 14028 专题)。
- 2021-10/11 账号盗取连环案:
ua-parser-js(月下载近千万)维护者账号被接管 4 小时,投递挖矿与密码窃取木马(CISA 告警、Sonatype 分析、Mandiant 深度分析);两周后coa、rc(合计约 2300 万周下载)因钓鱼接管被投毒(The Record、Rapid7)。 - 同期基础设施响应:谷歌开源 Sigstore(签名/透明日志);SLSA 框架发布 v0.1;npm 引入 automation tokens 与 granular tokens。
这一阶段的驱动因素:SolarWinds 让"攻击者不需要打穿你的网络,只需要打穿你的供应商"成为共识;赏金经济让高杠杆的供应链漏洞变成职业研究者的主业;远程办公普及放大了 CI 凭据的价值。
1.5 阶段四(2022–2023):投毒工业化、"抗议软件"与防御框架成形
- 2022-01 colors.js / faker.js 自毁:作者 Marak Squires 主动注入死循环与乱码,数千下游项目构建中断——"合法维护者本身也是供应链风险"进入视野。
- 2022-03 node-ipc / peacenotwar:作者 RIAEvangelist 以抗议俄乌战争为动机加入依赖
peacenotwar,后续版本检测到俄/白俄罗斯 IP 时用爱心表情覆写全盘文件,被定级 CVE-2022-23812,Snyk 直接按恶意软件处置(Snyk 分析)。"抗议软件(protestware)"一词流行,暴露地缘政治与开源信任的纠缠。 - 2022-05 PyPI
ctx事件:攻击者用仿冒邮箱域名冒充原作者接管账号,发布 0.1.7/0.2.2 版窃取环境变量(含 AWS 凭据),同案还有 PHP 的phpass(Sonatype、CrowdStrike)。Python 生态从此不再"天然安全"。 - 2022-12 PyTorch
torchtriton依赖混淆:圣诞夜攻击者向 PyPI 上传恶意torchtriton(该名字只存在于 PyTorch 官方私有 nightly 索引),窃取 AWS 凭据、Kubernetes 配置与 SSH 密钥;PyTorch 将依赖改名pytorch-triton并在 PyPI 注册同名占位包"占坑"(官方通告 issue #102439)。Birsan 理论在 AI 基建上的复现。 - 2023 防御侧大年:2022-07 PyPI 宣布 top 1% 关键项目强制 2FA(OpenSSF 资助硬件密钥)并于 2023 年扩展至全部上传账号;2023-04 SLSA v1.0 发布,构建轨道正式定稿(slsa.dev);2023-04 npm 上线 provenance(基于 Sigstore 的发布来源证明);2023-09 针对维护者的大规模钓鱼出现(仿冒 pypi.org 域名发"验证"邮件;来源层级注:此条为既有知识,本次修订检索未见独立来源链接,PyPI 官方有据可查的钓鱼通告为 2022-08 与 2025-07/09 两波,如 PyPI 博客 2025-07-28)。
驱动因素:加密货币价格波动驱动窃密恶意包的商业化;地缘战争把开源仓库变成表达与攻击的双重阵地;EO 14028 与 Log4Shell(2021-12)后的 SBOM 热潮让"可证明的构建"成为平台竞相提供的功能。
1.6 阶段五(2024):社会工程学登顶之年
- 2024-03 XZ Utils 后门(CVE-2024-3094,CVSS 10.0):身份"Jia Tan"的攻击者耗时约两年(自 2021 年起)混入 xz 项目,通过高频率"贡献"接替倦怠的原维护者 Lasse Collin 成为共同维护者,随后在 5.6.0/5.6.1 的发布 tarball(只污染发布包而非 git 主干,规避了源码审计)中注入针对 sshd 的远程代码执行后门;微软工程师 Andres Freund 因 PostgreSQL 基准测试中约 500ms 的 SSH 登录异常和 valgrind 报错而追查,3 月 29 日在 oss-security 披露,距后门进入主流发行版稳定分支约差 25 天(oss-security 披露存档、事件分析、Akamai 分析)。这是"维护者账号/项目接管"攻击的巅峰形态:不是偷账号,而是制造一个账号。
- 2024-06 polyfill.io 投毒:域名与 GitHub 账号被卖给中国公司 Funnull 后,服务的 polyfill.js 开始按条件(仅移动端、住宅 IP)向超过 10 万个引用它的网站访客注入重定向与恶意代码;Cloudflare/Fastly 封禁域名,各站被迫紧急移除引用(Sonatype、FOSSA)。供应链攻击从"包"扩展到"CDN 资源 + 商业资产转手"。
- 2024-11-14 PyPI 上线数字证明(attestation,PEP 740),配合 trusted publishing 自动生成(PyPI 官方博客)。
驱动因素:关键开源项目"一个人的图书馆"模式难以为继(Lasse Collin 的倦怠正是 Jia Tan 的切入点);npm 2024 年公开披露维护者邮箱泄露事件,钓鱼情报在地下市场明码标价(来源层级注:既有知识,本次修订检索未见直接来源链接)——攻击者开始系统化地经营"人",而不是"代码"。
1.7 阶段六(2025):蠕虫元年与 AI 武器化
- 2025-08-26 Nx "s1ngularity" 事件:攻击者利用 Nx CI 中 GitHub Actions 注入漏洞窃取 npm 发布令牌,发布 8 个恶意版本;payload 的最大亮点是调用本机的 AI CLI(Claude、Gemini 等)帮助扫描文件系统找密钥——AI 编程助手第一次被用作攻击工具(Wiz 分析)。
- 2025-09-08 chalk/debug 钓鱼事件:维护者 qix(Josh Junon)在仿冒 npm 支持页面(仿冒域名
npmjs.help,支持邮箱help@npmjs.help,域名 9 月 5 日刚注册)同时交出密码与 TOTP 2FA 码,发布 18 个(JFrog 口径;其他统计达 25 个)被植入加密货币剪贴板劫持代码的流行包版本,合计影响超过 20 亿周下载,部分载荷使用 AI 生成的混淆 JavaScript,约 2 小时后回滚;事后推动"抗钓鱼 MFA(passkey)"讨论(Wiz 分析、Aikido、JFrog、Palo Alto Networks)。 - 2025-09-14 Shai-Hulud 蠕虫(9 月 15–16 日间被各家发现,口径不一):npm 生态史上首个大规模自复制蠕虫——入侵维护者账号后经 @ctrl/tinycolor 等包扩散,窃取维护者令牌后自动向其维护的其他包发布带毒版本,感染 Zapier、PostHog、AsyncAPI 等厂商的包(各家口径 100+ 至 500+ 个包),并把偷到的密钥公开发到 GitHub 仓库(CISA 告警、Unit 42、Truesec、Wiz)。eslint-scope 2018 年"偷令牌发毒包"的雏形,七年后进化为全自动蠕虫。
- 2025-09-23 GitHub 发布《Our plan for a more secure npm supply chain》:granular/classic 长效令牌退役时间表、本地发布强制 2FA(逐步转向 WebAuthn/passkey)、全面推广 trusted publishing(OIDC 短时效发布)、npm 12 默认禁用安装脚本(GitHub 博客)。配套政策随后密集落地:2025-10-13 起 granular token 最长寿命压到 90 天(默认 7 天)、2025-12-09 吊销全部 classic token(Socket 博客,注:该站直接抓取被 403 拒绝,事实来自搜索摘要)。
- 2025-11-23/24 "Shai-Hulud 2.0(The Second Coming)":蠕虫第二波在数小时内波及 Zapier、ENS Domains、Postman、AsyncAPI 等数百个包版本,创建上万个存放窃取密钥的 GitHub 仓库,估计约 40 万条密钥外泄(StepSecurity、Arctic Wolf、Datadog)。
驱动因素:AI 编程助手普及 = 每台开发机上都有能读懂代码、有权限遍历文件的新攻击面;令牌长期驻留 CI 使一条钓鱼足以引发生态级连锁;蠕虫证明"供应链攻击可以像蠕虫病毒一样自增殖",倒逼平台把安全从建议改为强制。
1.8 阶段七(2026–当下):蠕虫常态化与平台强制安全(截至 2026-10-31)
- 2026-03-19/27 TeamPCP 级联攻击:以牟利为目的的团伙五天内连环攻陷四个广泛部署的包,展示"多跳"攻击编排。
- 2026-03-30/31 axios 事件:1.4 亿级周下载的 axios 出现 1.14.1/0.30.4 两个带毒版本。据 Zscaler 直接抓取的分析:攻击者(归因为朝鲜背景行为体)篡改维护者账号邮箱后直接用 npm CLI 发布,完全绕开 GitHub Actions 发布流水线,注入隐藏依赖 plain-crypto-js,postinstall 投放跨平台 RAT 并自我清理痕迹(纵轴稿另记录"约 89 秒自删"的说法,且该事件此前主要依赖二手来源;本报告以 Zscaler 直接抓取内容为准,归因表述保留"据 Zscaler 归因"限定)(Zscaler Research、Security Boulevard 通告、InfoDive Labs)。
- 同月 LiteLLM(PyPI)事件更说明"合法凭证"的杀伤力:带毒版本 1.82.8 通过 pip 哈希校验(因为是维护者凭证发布的),用 .pth 文件做到"不 import 也执行",窃取 AWS/GCP/Azure 令牌与 SSH、K8s 凭证,仅存活约三小时就被隔离,但该包日均下载 340 万(Zscaler Research 同文)。
- 2026-04 Wiz《The Supply Chain Attack Playbook》系统性复盘 axios、LiteLLM 等事件,指出包生态"重复被穿透"的结构性原因(Wiz 博客);同期 48 小时内 npm/PyPI/Docker Hub 三起独立投毒被 GitGuardian 记录(GitGuardian)。
- 2026-05 "Mini Shai-Hulud":5 月 11 日 TanStack 事件曝光——攻击者(TeamPCP)未窃取任何 npm 凭证,而是利用三个 GitHub Actions 漏洞组合(fork 仓库改名规避检测、pull_request_target 工作流执行 fork 代码、向 Actions 缓存注入带毒 pnpm store),维护者合并 PR 后发布工作流从缓存恢复恶意代码,从 runner 进程内存提取 OIDC 令牌并发布带毒包,波及 @tanstack(含周下载约 1200 万的 react-router)、@uipath、@mistralai、@opensearch-project 等 150+ 版本(Snyk 口径:42 个 @tanstack 包的 84 个产物),并新增三通道冗余外传、针对"令牌被吊销即
rm -rf ~/"的报复性 wiper 守护进程(Wiz、Snyk)。5 月 20 日前后 The Hacker News 报道的更广波次(GitHub Actions 缓存投毒等手法)波及 320+ npm 包、GitHub Actions 与 VS Code 扩展(The Hacker News)。 - 2026-05-28/29 微软两份披露:5 月 28 日披露 typosquatting 窃取云与 CI/CD 凭据活动(Microsoft Security Blog);5 月 29 日披露一批共 33 个恶意 npm 包(三个账号发布;纵轴稿另有"后更新至 45 个"的说法,最终稿修订检索未见 45 的独立来源,按报告保守口径原则统一取 33)滥用依赖混淆——伪装成 9 个企业内部命名空间(@sber-ecom-core 等,甚至仿冒 SberPay 组件),版本号抬到 100.100.100 以赢得解析,postinstall 钩子下载约 17KB 的"纯侦察"载荷并带服务端开关(RECON_ONLY 标志可远程翻转为完全利用)(Microsoft Security Blog)。这是两条不同的活动,详见附录 A 第 4 条。
- 2026-05-29:Red Hat 发布 RHSB-2026-006:VS Code 恶意扩展导致 GitHub 账号接管(Red Hat 通告);PyPI "Hades" 活动中 26 个包被植入 import 时即执行的恶意代码(Checkmarx)。
- 2026-06/07/08:@redhat-cloud-services 命名空间投毒事件(2026-06:Red Hat 员工 GitHub 账号被劫持,32 个包、共 96 个恶意版本被发布,"Miasma"安装即执行的窃密载荷,被称为 Mini Shai-Hulud 变体)(Step Security、SecurityWeek);Unit 42 发布 Shai-Hulud 时代 npm 威胁图景分析(蠕虫化、CI/CD 持久化、多阶段)(Unit 42);8 月 Shai-Hulud 关联蠕虫 ChainDrop 波及 keyv/cacheable 生态(部分统计口径达 444+ 包、约 20 亿月下载)(Zscaler ChainDrop 分析)。政策侧,美国 OMB 于 2026-01-23 发布 M-26-05 备忘录《Adopting a Risk-based Approach to Software and Hardware Security》,撤销 M-22-18/M-23-16 的统一"Common Form"造证要求,把 EO 14028 下的强制造证转向"基于风险"的路径(OMB M-26-05 原文)。
- 截至本报告日(2026-10-31):检索未发现 2026 年 9–10 月经多家独立机构确认的新的标志性投毒事件;行业主线是 npm/PyPI trusted publishing 的全面迁移(npm 目标 2027 年 1 月移除 2FA-bypass granular token 的直接发布,此后发布路径以 trusted publishing(OIDC)或 stage-only token + 人工 2FA 审批为主(GitHub 社区讨论))。
驱动因素:攻击重心从"发布一次性毒包"转向"攻占 CI/CD 执行层(Actions 漏洞链、缓存投毒、扩展投毒)+ 蠕虫化自增殖";防御重心从"开发者自觉"转向"平台默认强制"(2FA/passkey、OIDC trusted publishing、安装脚本默认禁用)。
1.9 时间线速查表
| 时间 | 事件 | 攻击链类型 | 来源 |
|---|---|---|---|
| 1984 | Thompson《Trusting Trust》 | 理论奠基 | ACM |
| 2015-09 | XcodeGhost(4000+ 应用) | 构建工具链投毒 | Threatpost |
| 2016-03 | left-pad 下架风波 | 生态脆弱性 | The New Stack |
| 2017-08 | crossenv 等 38 个仿冒包 | 恶意包/typosquatting | npm 博客 |
| 2018-07 | eslint-scope 令牌窃取 | 维护者账号被盗 | ESLint |
| 2018-11 | event-stream 后门 | 维护者接管+定向攻击 | 取证文章 |
| 2019-01 | PEAR 安装器被替换 | 注册站投毒 | The Hacker News |
| 2020-12 | SolarWinds SUNBURST | 构建系统投毒(国家级) | FireEye |
| 2021-02 | Birsan 依赖混淆披露(赏金 13 万美元+) | 依赖混淆 | 原文 |
| 2021-04 | Codecov 脚本被篡改(潜伏约 2 个月) | CI 管道投毒 | Codecov |
| 2021-05 | EO 14028 / SBOM | 政策里程碑 | NIST |
| 2021-10/11 | ua-parser-js;coa/rc | 账号接管连环案 | CISA |
| 2022-03 | node-ipc/peacenotwar | 维护者自投毒(抗议) | Snyk |
| 2022-05 | PyPI ctx | 账号冒充接管 | Sonatype |
| 2022-12 | torchtriton 依赖混淆 | 依赖混淆 | PyTorch issue |
| 2023-04 | SLSA v1.0(规范现已演进至 v1.2) | 防御框架 | slsa.dev |
| 2024-03 | XZ Utils 后门 | 项目/维护者接管(国家级)*跨链注:后门本体注入发布 tarball 构建产物,同时属构建产物投毒,见 2.2.3 | oss-security |
| 2024-06 | polyfill.io | 资产转手+CDN 投毒 | Sonatype |
| 2024-11 | PyPI attestation 上线(PEP 740) | 防御里程碑 | PyPI |
| 2025-08 | Nx s1ngularity(AI CLI 滥用) | CI 漏洞→发布令牌被盗 | Wiz |
| 2025-09-08 | chalk/debug 钓鱼(20 亿周下载,连 TOTP 一并被钓走) | 钓鱼接管 | Wiz |
| 2025-09-14 | Shai-Hulud 蠕虫(100–500+ 包) | 自复制蠕虫 | CISA |
| 2025-09-23 | npm 安全计划;10-13 token 限寿;12-09 classic 吊销 | 平台强制安全 | GitHub、Socket |
| 2025-11-23 | Shai-Hulud 2.0(约 40 万密钥外泄) | 蠕虫第二波 | StepSecurity |
| 2026-03 | TeamPCP 级联;axios RAT;LiteLLM | CI 链投毒/账号接管 | Zscaler |
| 2026-05 | TanStack/Mini Shai-Hulud(150+ 版本,320+ 包波次);微软两份披露;RHSB-2026-006 | Actions 漏洞链+缓存投毒/依赖混淆侦察/扩展投毒 | Wiz、Microsoft、Red Hat |
类别注:本表"攻击链类型"列采用宽口径标注,与 2.2 节的四链分类体系(依赖混淆、恶意包、维护者账号被盗、构建系统投毒)不完全对齐。其中"依赖混淆/恶意包/维护者账号被盗/构建系统投毒/构建工具链投毒"属四链及其近义标注;"理论奠基/生态脆弱性/政策里程碑/防御框架/防御里程碑/平台强制安全"属背景与防御侧里程碑,不是攻击链;"CI 管道投毒/注册站投毒/资产转手+CDN 投毒/自复制蠕虫/钓鱼接管/账号接管连环案/维护者自投毒"属跨链或派生形态。非四链标注仅为保留事件语境,不参与 2.4.2 的防御覆盖矩阵。
1.10 纵轴贯穿性规律
- 攻击杠杆永远指向"被信任的自动化":编译器(1984)→ 开发工具(2015)→ 安装脚本(2017)→ 维护者身份(2018–2024)→ CI/CD(2021–2026)→ AI CLI(2025)。每次防御补上一环,攻击就移向信任链的下一环。
- 命名催生防御:依赖混淆在 2021 年被命名后,各生态的混淆面在 1–2 年内快速收敛;蠕虫在 2025 年被命名后,npm 的强制安全(trusted publishing/2FA/脚本默认禁用)在 3 个月内公布并启动执行(纯令牌发布封禁要到 2027 年初才完成)——公开披露本身就是最强的防御催化剂。
- 成本不对称在恶化:一次 TOTP 钓鱼可换取 20 亿周下载的分发权;一条被蠕虫偷走的令牌可自增殖到数百个包。防御必须默认"单点身份必然失守"。
- 防御的终点是"可证明"而非"可信任":从 npm 博客式的"请及时改密码"(2018),到 SLSA/attestation/trusted publishing 的"密码学证明这条包是谁在哪条流水线上构建的"(2023–2026),行业完成了从声誉信任到证据信任的范式迁移。
二、横轴:横向对比(时间截面 2026-10-31)
2.1 威胁量级:为什么防御路线必须换
2025 年 9 月之前,"软件供应链攻击"通常被当作单一话题讨论;2025 年 9 月至 2026 年 6 月,npm/PyPI 生态连续爆发了一组可明确归类到四条不同攻击链的事件(Shai-Hulud 蠕虫、chalk/debug 钓鱼入侵、TanStack CI 缓存投毒、微软披露的依赖混淆侦察包等),使得在当下时间截面做横向对比有了难得的同期样本。
宏观量级(Sonatype 2026 年报告,覆盖 2025 全年):新发现恶意开源包 454,600+ 个,同比增长 75%,累计已识别/拦截恶意包超过 123.3 万个(覆盖 npm、PyPI、Maven、NuGet、Hugging Face);其中约 99% 集中在 npm;2026 年一季度又新增 21,764 个,平均每六分钟一个(Sonatype State of the Software Supply Chain 2026)。这个量级决定了:任何只依赖"事后下架 + CVE 库匹配"的防御路线都已不够用——这是下面三层对比的现实约束。
2.2 层一:四条攻击链横向对比
2.2.1 对比总表
| 维度 | 依赖混淆 | 恶意包(typosquat/伪装) | 维护者账号被盗 | 构建系统投毒 |
|---|---|---|---|---|
| 攻击入口 | 包管理器的版本解析规则 | 开发者/CI 的搜索与引入行为 | 维护者本人的凭证与身份 | CI/CD 流水线、构建节点、构建脚本 |
| 前置条件 | 目标内部包名在公共源未注册;配置未锁定私有源优先 | 存在可被模仿的知名包名或可蹭的热点 | 维护者开启弱 2FA/被钓鱼;注册商/邮箱侧失守 | Actions 可被 fork 触发、缓存可写、秘密暴露于 runner 内存 |
| 攻击成本 | 低(注册包名即可),侦察型成本极低 | 中低(批量自动化),规模化依赖脚本 | 中(钓鱼基础设施 + 域名注册) | 高(需理解目标 CI 细节),但蠕虫化后边际成本递减 |
| 潜伏与持续性 | 一次性触发型(install 即执行) | 可长期潜伏,靠量取胜 | 发布恶意版本后依赖版本残留 | 最深:可回溯篡改历史 tag/缓存,或如 XZ 般经营两年 |
| 典型影响面 | 开发者终端、构建网络(内网横向) | 终端用户与 CI,量大面广 | 单包背后全部下游(可达 20 亿周下载) | 全部信任该构建产物的下游,含发行版/企业产品 |
| 检测难度 | 低-中(版本号异常、来源异常易发现) | 中(量大、混淆强时难) | 中高(发布走合法凭证,pip hash 校验都能通过) | 高(XZ 藏在编译产物中;TanStack 用合法 OIDC 令牌发布) |
| 代表事件 | Birsan 2021(13 万美元赏金);微软 2026-05 披露的 33 包侦察活动 | Sonatype 2025 年统计的 45.46 万新恶意包;crossenv 2017 | chalk/debug 2025-09;axios 2026-03;eslint-scope 2018 | SolarWinds 2020;XZ Utils 2024(跨链样本,见 2.2.3);tj-actions 2025-03;TanStack 2026-05 |
2.2.2 逐项说明(事件细节见纵轴对应年份,此处只补对比所需增量事实)
(1)依赖混淆:规则漏洞型,成本最低、最"自动化"。 奠基事件是 Birsan 2021(纵轴 1.4 节)。五年后这条链并未消失反而升级:微软 2026-05-29 披露的 33 个恶意 npm 包是典型新形态——伪造企业命名空间 + 超高版本号 + 带"侦察/完全利用"远程开关的载荷,说明攻击者已把依赖混淆从"一次性进入内网"进化为"长期驻留的可切换侦察桩"(Microsoft Security Blog)。
(2)恶意包:数量型,防御重心在"引入前行为分析"。 这是规模最大的一条链(Sonatype 口径见 2.1 节);报告同时指出攻击者正从简单 typosquatting 转向"多阶段载荷链、自传播蠕虫、滥用仓库平台功能"(Sonatype 2026)。Shai-Hulud 既是恶意包链的巅峰,也是账号被盗链的放大器——两链融合的标志性样本(见 2.2.3 小结)。
(3)维护者账号被盗:身份型,单点失守即全下游沦陷。 代表事件 chalk/debug(纵轴 1.7 节)的最初失守点不是 npm 本身,而是注册商/邮箱侧的钓鱼;axios(2026-03)则展示了"改邮箱→直发"的绕道打法。两案共同点:发布走合法凭证,传统校验全部失效。
(4)构建系统投毒:纵深型,最难检测、影响面最深。 除 SolarWinds(国家级、构建服务器注入)与 XZ(两年社会工程)外,2025–2026 年出现了 CI 层面的两条新变体:tj-actions/changed-files(CVE-2025-30066,2025-03-14)——该 GitHub Action 的全部历史版本 tag(v1–v45.0.7)被回溯改指向恶意提交,转储 runner 内存中的 GITHUB_TOKEN 与云密钥到构建日志,波及约 2.3 万个仓库,源头可能是关联 Action reviewdog/action-setup 被入侵,由 StepSecurity Harden-Runner 的出网遥测发现(GitHub Advisory GHSA-mrrh-fwg8-r2c3、Wiz 分析、CISA);以及 TanStack/Mini Shai-Hulud(2026-05)——不偷任何凭证,纯靠 Actions 漏洞链(fork 改名规避检测、pull_request_target 执行 fork 代码、Actions 缓存投毒)+ runner 内存提取 OIDC 令牌完成投毒(Wiz、Snyk、OpenAI 响应)。这条链正在从"人力经营两年"(XZ)进化为"自动化漏洞链 + 蠕虫化"(TanStack/TeamPCP)。
2.2.3 层一小结:成本-纵深光谱与链式融合
四条链构成一个"成本-纵深"光谱:依赖混淆最便宜、最易检测;恶意包靠数量取胜;账号被盗单点影响最大且检测窗口极短;构建系统投毒最难检测、潜伏最深。2025–2026 年的最重要变化是四条链开始融合:Shai-Hulud 本质上是"账号被盗→恶意包→窃取令牌→再发布"的链式组合;TanStack 是"构建投毒→OIDC 令牌→恶意发布"的组合。拆链研究的价值因此从"分类学"变成了"断链点定位学"。
跨链样本说明(XZ Utils 的归属):XZ Utils 在 1.9 时间线中归入"项目/维护者接管",而在 2.2.1/2.2.2(4) 又被列作构建投毒的代表事件——因为它是一个典型的跨链样本:入口是维护者接管("Jia Tan" 以两年社会工程取得共同维护者身份与发布权),落点是构建产物投毒(后门只注入发布 tarball 而非 git 主干)。本报告把它列作构建投毒代表事件时,取的是"构建产物被污染"这一环节,不否认其账号/身份侧入口;时间线表已加注对应说明。同理,TanStack 是"构建投毒×恶意发布"、Shai-Hulud 是"账号被盗×恶意包×蠕虫自增殖"的跨链样本。
2.3 层二:与相邻/替代研究课题的横向对比
| 相邻课题 | 关注对象 | 核心问题 | 与本课题的关系 | 立足 2026 截面的评价 |
|---|---|---|---|---|
| CVE 漏洞利用链(Log4Shell 式) | 已发布组件中的非故意缺陷 | 漏洞如何被发现与武器化 | 同属"上游引入风险",但漏洞是意外、供应链攻击是蓄意,检测逻辑完全不同 | 传统 SCA 以 CVE 库为核心,对"没有 CVE 的恶意版本"(如 LiteLLM 1.82.8)完全盲视;本课题与其互补而非替代 |
| 提示注入与 Agent 安全 | LLM/Agent 的运行时输入面 | 不可信内容如何劫持 agent | 交互面在"运行时",本课题在"引入时" | 两课题在 AI 时代交汇:恶意包开始针对 .claude/、.vscode/ 目录下手(TanStack 事件中 Wiz 明确建议审计这两个目录),Agent 自动安装依赖又反向放大恶意包面 |
| 身份与凭证安全 | PAT/令牌/OAuth 全生命周期 | 凭证如何泄露与滥用 | 是本课题第 3、4 条链的"因" | 2025–2026 事件几乎都终结于"凭证被偷/令牌滥用";npm 2025-10-13 起 granular token 最长 90 天(默认 7 天)、2025-12-09 吊销全部 classic token,正是两个课题的交叉产物 |
| AI 模型供应链(Hugging Face 投毒) | 模型权重、数据集、MCP/Skill 资产 | 模型文件与提示层被植入恶意行为 | 同构问题在新介质上的迁移 | Sonatype 2026 报告已把 Hugging Face 纳入统计范围;方法论高度可迁移(来源证明、行为扫描),属于本课题的自然外延 |
| 容器镜像/制品仓库安全 | 镜像层、基础镜像、制品库 | 制品被篡改或投毒 | 本课题第 4 条链在容器场景的投影 | 逻辑同构(谁来证明制品出自可信构建),防御工具同源(签名 + 准入策略),可合并治理 |
层二结论:本课题的不可替代定位是——它研究的是"信任的入口":其他课题研究"已经进来的东西如何作恶/出洞",本课题研究"那个东西凭什么被允许进来"。2026 年的攻击者已经把主战场从"利用软件缺陷"转向"滥用软件的信任结构"(版本解析规则、维护者身份、CI 缓存),因此该课题处于威胁演化的主轴上,而非相邻课题的子集。
2.4 层三:防御方案体系横向对比
2.4.1 五类防御路线
| 路线 | 代表方案 | 能力(防什么) | 成本 | 成熟度 | 主要局限 |
|---|---|---|---|---|---|
| A. 来源证明/签名类 | SLSA(现 v1.2,构建轨道 L1–L3)、Sigstore/cosign、npm/PyPI Trusted Publishing(OIDC)、PyPI PEP 740 attestations | 证明"产物出自可信构建/可信发布者",防凭证滥用与构建篡改 | 中高:需改造发布流程与验证端 | 高:npm 已吊销 classic token 强制迁移;SLSA 规范已到 v1.2(slsa.dev FAQ) | 不证明"代码本身无害"(合法凭证也能发恶意版本——LiteLLM);验证端落地率仍低 |
| B. 组件清单类(SBOM) | CycloneDX / SPDX,签署的 SBOM + SLSA attestation | 事件响应时快速定位波及面;合规(美 EO 14028 脉络) | 中:生成自动化程度高,消费端弱 | 高(生成)/中(消费与执行) | 事后盘点型,不能阻止引入;对"运行时才显现"的恶意行为无感 |
| C. 行为分析类 | Socket(行为检测 install 脚本/网络/子进程,覆盖 9 生态,2026-05 完成 6000 万美元 C 轮融资、估值 10 亿美元,Thrive Capital 领投(Socket 官方公告))、OpenSSF Package Analysis | 抓"没有 CVE 的新恶意包",正是恶意包链的主武器 | 低-中(开源项目免费) | 快速成熟中 | 误报治理成本;对深度混淆(AI 生成载荷)与构建期投毒覆盖有限 |
| D. CVE/SCA 类 | Snyk、GitHub Dependabot、OWASP Dependency-Check | 已知漏洞跟踪、许可证合规、升级引导 | 低-中 | 最高(十年成熟度) | 对四条攻击链整体几乎"零覆盖"——它们防的是缺陷不是投毒 |
| E. 入口与运行时管控类 | Sonatype Firewall(入口策略门禁)、私有/代理源 + allowlist、CI 出网管控、StepSecurity Harden-Runner(egress 遥测,tj-actions 事件的实际发现者)、Action pin 到 commit SHA | 在引入与执行两点建立闸门;提供取证数据 | 中-高(策略运营负担) | 高(企业侧标配) | 需要组织级纪律;对开发者本机(最常失守处)覆盖最弱 |
2.4.2 防御 × 攻击链覆盖矩阵(关键交叉洞察)
| 防御路线 | 依赖混淆 | 恶意包 | 账号被盗 | 构建投毒 |
|---|---|---|---|---|
| A 来源证明/签名 | ◐(源配置校验辅助) | ◐(证明发布者≠证明安全) | ●(Trusted Publishing 直击令牌钓鱼收益) | ●(SLSA L3 隔离 + 证明) |
| B SBOM | ○ | ◐(快速止血) | ◐(快速止血) | ◐(波及面定位) |
| C 行为分析 | ◐ | ● | ◐(发版行为异常可标) | ◐(缓存/依赖变更可标) |
| D CVE/SCA | ○ | ○(恶意包多数无 CVE) | ○ | ○ |
| E 入口/运行时管控 | ●(私有源优先+锁版本) | ●(引入闸门+出网管控) | ◐(发布策略异常告警) | ●(egress 遥测 + pin SHA) |
(● 直接有效 ◐ 部分有效 ○ 基本无效)
矩阵揭示两个事实:第一,没有任何单一路线能同时压住四条链。 CVE/SCA 类(业界普遍观察中企业采购最倚重的一类——判断性表述,本次修订未检索到采购占比统计)对供应链攻击几乎整体无效——这正是 LiteLLM 带毒版本"通过 pip 哈希校验"能成立的原因:哈希校验验证的是"你拿到的是仓库里那份",而仓库里那份本身就是恶意的。第二,A+E(来源证明 + 入口/运行时管控)是唯一在四条链上都有直接有效成分的双路线组合——A 行在账号被盗、构建投毒两列为 ●,E 行在依赖混淆、恶意包、构建投毒三列为 ●,两线合并后四条链上均有 ●,且是唯一做到这一点的两线组合;C 作为恶意包链的前置补充——这与业界 2025 年后收敛出的"SBOM(清单)+ Sigstore(来源)+ SLSA(构建完整性)+ policy-as-code(强制执行)"分层模型一致。
2.5 按事件反推的防御点清单(两章节合并版)
以下清单合并了纵轴稿"结合真实事件总结的防御点"与横轴稿"按事件反推的防御清单",去掉重复项后的完整版本:
- Birsan 2021 / torchtriton 2022 → 私有源优先与命名占位:私有包一律使用明确的 registry scope 并逐包显式指定源(npm 的
.npmrcper-scope registry、Artifacts upstream、pip 仅用可信 index);内部包在公共源预防性占位(PyTorch 官方事后做法);锁文件锁定精确版本并 review 新增依赖;CI 中禁用"自动取更高版本"。这是四条链中防御最成熟的一条。 - crossenv 2017 / ctx 2022 / 微软 2026-05 typosquat → 让安装动作默认不可信:以 Socket/StepSecurity/Datadog 等行为检测替代纯漏洞库匹配(对 postinstall、网络外传、环境变量读取告警);npm 12 起默认禁用安装脚本、显式审批;锁文件 + 依赖白名单 + 新依赖人工准入;对周下载量异常低的"新包"保持怀疑(刷量制造的虚假流行度同样可被识别);CI 出口流量管控。
- eslint-scope 2018 / chalk-debug 2025 / axios 2026 → 身份防线必须"抗钓鱼",且注册商与邮箱治理等同包安全:passkey/WebAuthn 级抗钓鱼 MFA 取代 TOTP/短信(chalk/debug 连 TOTP 都被钓走,社区已有共识);发布走 trusted publishing(OIDC 短时效令牌),CI 中不再存长效 npm/PyPI token;令牌最小权限 + 90 天强制轮换;对"维护者邮箱被改""绕过 CI 直发"设策略告警(axios 的实际路径);发布走组织化双人文审;对"npm 支持"类钓鱼做常态化演练。仿冒支持域名 npmjs.help 在事发前三天(2025-09-05)注册,说明域名注册监控本可预警。
- SolarWinds 2020 / Codecov 2021 / tj-actions 2025 / TanStack 2026 → 构建与 CI 全链最小权限 + 可证明构建:GitHub Actions 一律 pin 到完整 commit SHA(tag 可回溯改写);
GITHUB_TOKEN最小权限、对 fork PR 限制 secrets、pull_request_target 收敛;把 Actions 缓存、第三方 CI 组件(coverage 上传脚本、action、扩展)视为可被投毒的代码而非工具;构建密封化(hermetic build)并产出 SLSA provenance / Sigstore 签名 / PyPI attestation / npm provenance,让"这个产物由哪条可信流水线构建"可验证。 - TanStack 2026 的响应顺序警告:OIDC 令牌提取自 runner 内存,需要 runner 加固与令牌短时效;事件响应必须先清除 wiper 守护进程、再轮换 GitHub 令牌(Wiz 明确警告顺序颠倒会触发
rm -rf ~/毁盘)。(注:本条是事件响应的顺序警示而非事前防御点,与清单其余条目性质不同,故单独保留并加注。) - event-stream 2018 / XZ 2024 → 人的可持续性:关键依赖(尤其个人维护的底层库)纳入 OpenSSF/Alpha-Omega 类资助与关键性评分监护;多名维护者 + 组织背书降低单点接管价值;对突然高频提交、急于接管发布权的贡献者保留警惕与隔离验证;下游采用 vendor/锁文件降低对上游突变的暴露;发行版从源码/非上游渠道构建。
- Shai-Hulud 2025 两波 → 蠕虫化要求"令牌最小权限 + 环境隔离":蠕虫靠开发者环境里的长期 npm 令牌自我传播;CI 与本机凭证分离、发布令牌限定到单包、lockfile 审计发布窗口,是切断传播的三个点。
- Codecov 2021 / Shai-Hulud / polyfill.io → 假设已沦陷时的止损能力:CI/发布审计日志实时告警(异常发布、异常 tag 移动);订阅 CISA/厂商 IoC 并预设"知名包带毒版本"的应急清单(chalk/debug 的 2 小时止损靠的就是这类监测);密钥自动轮换(短时效 OIDC 本质上把"泄露半径"压到分钟级);SBOM + provenance 让"我是否中招"能在小时级回答,而不是像 Codecov 那样靠两个月的追溯。
三、交叉洞察:两轴结合说明了什么
3.1 五个判断
判断一:主战场已经从"软件缺陷"迁移到"信任结构",本课题位于威胁演化的主轴。 纵轴显示攻击杠杆的迁移路径(编译器→工具→脚本→身份→CI→AI CLI),横轴则显示被利用的全是"信任机制"而非"内存错误":版本解析规则(依赖混淆)、维护者身份(钓鱼)、CI 缓存与 OIDC(构建投毒)。两轴互证:这不是同一战场的不同打法,而是不同战场——它决定了传统漏洞管理范式(扫 CVE、打补丁)对本课题整体失配。
判断二:攻击链已从"分类"走向"融合",防御必须从"单点工具"走向"断链组合"。 2021 年四条链还是四个独立话题;2025–2026 年 Shai-Hulud 是"账号被盗→恶意包→窃取令牌→再发布"的复合体,TanStack 是"构建投毒→OIDC 令牌→恶意发布"的复合体。横轴覆盖矩阵进一步证明单一路线(尤其业界普遍观察中企业采购最倚重的 CVE/SCA 类,判断性表述)对供应链攻击整体盲视;A+E 是唯一在四条链上都有直接有效成分的双路线组合(矩阵口径见 2.4.2),再加上 C 对恶意包链的前置补充,构成当前截面下的最优覆盖(A+E+C)。
判断三:命名催生防御,公开披露是最强的防御催化剂——但窗口期正在缩短。 纵轴的两个时间差是最好的证据:依赖混淆 2021 年被命名后 1–2 年内混淆面快速收敛;Shai-Hulud 2025 年 9 月被命名后,npm 强制安全 3 个月内公布并启动执行(纯令牌发布封禁预计 2027 年初才完成)。但横轴同时显示,2026 年一季度的重大事件至少已有三起(TeamPCP 级联、axios、LiteLLM,见 1.8),加上 4 月 GitGuardian 记录的 48 小时内三起独立投毒,说明转型尚未完成——新防线(未配置 Trusted Publishing 的团队、验证端缺失)与旧手段并存,正是当下最脆弱的窗口期。
判断四:成本不对称仍在恶化,且攻击者的"产品化"程度超过防御者的组织化。 攻击侧出现 AI 生成混淆载荷(chalk/debug、Nx)、蠕虫自增殖(Shai-Hulud 两波)、报复性 wiper(TanStack)、可远程翻转的侦察桩(微软 2026-05 披露);防御侧虽完成了"token 革命",但本质都是把攻击收益降回均值,而非结构性反超。防御必须默认"单点身份必然失守",把重心放在泄露半径与止损速度上。
判断五:防御的终点是"可证明"而非"可信任",且本课题的结论有效期只有 6–12 个月。 从 2018 年"请及时改密码"到 2023–2026 年"密码学证明这条包是谁在哪条流水线上构建的",行业完成了从声誉信任到证据信任的范式迁移(SLSA v1.2、PEP 740、trusted publishing)。同时,与横轴层二中多数相邻课题(漏洞、身份、容器)方法论相对稳定不同,本课题的事件样本在 12 个月内全部刷新过一轮——本报告的对比结论需要以事件为锚点滚动更新。
3.2 对读者的判断与建议
优先级排序(如果只做三件事):第一,把发布凭证换成 OIDC trusted publishing + passkey(直击账号被盗链的全部收益);第二,把 CI 里的 Action pin 到 commit SHA 并把 Actions 缓存纳入威胁模型(直击构建投毒链的新入口);第三,为私有依赖配置 per-scope 源锁定并在公共源占位(成本最低、收益确定的一条)。
分角色建议:
- 应用开发者/企业安全团队:按"SBOM(清单)+ Sigstore/Trusted Publishing(来源)+ SLSA(构建完整性)+ policy-as-code(强制执行)"分层模型补齐,而不是继续加购 CVE/SCA 扫描器;引入前上行为分析(Socket 类),运行时上出网遥测(Harden-Runner 类);对"绕过 CI 直发、改邮箱、异常高版本号"设策略告警;准备"知名包带毒版本"的应急清单与密钥轮换预案(chalk/debug 的 2 小时止损是可复制的样板)。
- CI/平台工程:Actions pin SHA、pull_request_target 收敛、fork PR 不给 secrets、缓存视为不可信输入、egress 遥测作为标配;发布通道与开发者本机凭证分离;牢记 TanStack 的响应顺序——先清 wiper 再轮换令牌。
- 开源维护者:迁移 passkey/WebAuthn,启用 trusted publishing;对"热心接管"的贡献者保留隔离验证期(event-stream 与 XZ 的共同教训);不健康的项目尽早寻找组织背书或资助,"一个人的图书馆"本身就是攻击面。
- 采购决策者:评估供应商时把"是否提供 SLSA provenance/签名、是否使用 trusted publishing"作为硬指标——"证明你的软件是怎么造出来的"在 EO 14028 脉络下已经是合规命题,在 Shai-Hulud 之后是生存命题。
一个反直觉的提醒:防御投入不要按"事件热度"分配,按覆盖矩阵的缺口分配。依赖混淆的防御(per-scope 源锁定)几乎零成本且已被验证,却仍是最常见缺口;而按业界普遍观察(判断性表述,非采购统计),最多的预算往往花在对四条链整体无效的 CVE/SCA 工具上。
3.3 本报告的已知局限
- axios 事件的证据层级:纵轴稿标注其最初仅有二手来源;横轴稿通过 Zscaler 直接抓取补充了细节与"朝鲜背景行为体"归因。本报告以 Zscaler 直接抓取内容为准,但归因表述保留"据 Zscaler 归因"限定,官方一手通告截至写作日未见,后续验证为准。
- 统计口径差异:Shai-Hulud 波及包数各家口径 100+ 至 500+;chalk/debug 涉事包数 18(JFrog)至 25(其他统计);第二波外泄密钥条数(约 40 万条)为 Datadog 估计。正文均取保守区间表述。
- "没有新事件"≠"没有事件":截至 2026-10-31 未检索到 9–10 月经多家独立机构确认的新标志性事件,但供应链攻击的"沉默窗口"通常以月计(Codecov 潜伏约 2 个月、xz 后门潜伏约 1 个月),近两个月的平静不能外推为趋势。
- 来源层级:横轴稿的个别事实来自"搜索摘要"或"既有知识"(如 Birsan 原文未直接抓取、SolarWinds 早期细节、Socket 博客 403),纵轴稿的个别事件细节为二手转述;本文继承这些标注,读者引用前请回溯原始链接核对。
附录 A:两章节矛盾消解记录
综合两份章节稿时发现并按以下方式消解的口径差异:
- chalk/debug 涉事包数:纵轴 25 个 vs 横轴 18 个(JFrog 口径)。→ 取"18 个(JFrog 口径;其他统计达 25 个)",两者均为检索所得,无法进一步仲裁。
- Shai-Hulud 发现日期与包数:纵轴 2025-09-14、500+ 包 vs 横轴"9 月 15–16 日发现、各家口径 100+ 至 500+"。→ 取"2025-09-14(9 月 15–16 日间被各家发现,口径不一),各家口径 100+ 至 500+ 包"。
- Birsan 赏金数额:纵轴"合计数十万美元" vs 横轴"超过 13 万美元"。→ 取更精确的"超过 13 万美元"。
- 微软 2026 年 5 月披露:纵轴引 05-28《typosquatted npm packages used to steal cloud CI/CD secrets》(typosquatting 窃凭据),横轴引 05-29《33 恶意 npm 包滥用依赖混淆》。→ 判定为两条独立披露的活动,正文分别列出并保留两个链接,不做合并。包数口径:纵轴稿曾记"后更新至 45 个",最终稿修订检索未见 45 的独立来源(对应链接标题与检索所得口径均为 33),按报告保守口径原则统一取 33。
- axios 事件来源层级:纵轴"仅二手来源、细节待一手验证" vs 横轴 Zscaler 直接抓取(含 DPRK 归因、改邮箱、绕开 CI、plain-crypto-js 细节)。→ 采用横轴的直接抓取内容为主线,保留纵轴的"约 89 秒自删"与"1.4 亿周下载"说法并注明出处层级,归因加"据 Zscaler"限定。
- SLSA 版本:纵轴"2023-04 v1.0" vs 横轴"现 v1.2"。→ 非矛盾:v1.0 为 2023-04 定稿版本,规范现已演进至 v1.2,正文按时间序表述。
- TanStack 事件日期与规模:纵轴"5 月 20 日前后报道的 Mini Shai-Hulud 波及 320+ 包、42 个 TanStack 包" vs 横轴"5 月 11 日事件曝光、150+ 版本(Snyk 口径 42 个 @tanstack 包 / 84 个产物)"。→ 取"5 月 11 日 TanStack 事件曝光(Wiz),5 月 20 日前后 The Hacker News 报道更广波次 320+ 包";规模两种口径并存(150+ 版本 / 42 包 84 产物)。
- npm token 政策日期:纵轴仅提 2025-09-23 计划 vs 横轴给出 2025-10-13 granular 限寿、2025-12-09 classic 吊销的具体执行日期。→ 合并两者(计划 + 执行),并标注 Socket 博客为搜索摘要来源(直接抓取 403)。
- XZ Utils 的链归属:1.9 时间线表归"项目/维护者接管",2.2.1/2.2.2(4) 又列为"构建系统投毒"代表事件,初稿未作跨链解释。→ 定性为跨链样本:入口是维护者接管(两年社会工程取得发布权),落点是构建产物投毒(后门只注入发布 tarball 而非 git 主干)。正文 2.2.3 已补"跨链样本说明",时间线表已加注,不强行归入单链。
附录 B:术语表
正文涉及、但对非本领域读者可能构成门槛的术语,按首次出现顺序(审读意见要求补注的 SCA、OIDC、TOTP、attestation、egress 等均在内):
| 术语 | 释义 |
|---|---|
| CVE | 公开漏洞编号库。供应链投毒投放的是"恶意版本"而非"有缺陷版本",多数没有 CVE 编号,这是 SCA 对其盲视的根源 |
| SCA(Software Composition Analysis,软件成分分析) | 扫描项目依赖树、对照 CVE 库给出已知漏洞告警的工具类别(代表:Snyk、Dependabot、OWASP Dependency-Check),同时承担许可证合规 |
| SBOM(Software Bill of Materials,软件物料清单) | 机器可读的"本产品包含哪些组件与版本"清单(CycloneDX/SPDX 格式),用于事件响应时定位波及面;不能阻止引入 |
| 2FA / MFA | 双因素 / 多因素认证 |
| TOTP | 基于时间同步的一次性验证码(认证器 App 生成的 6 位数字)。可被实时钓鱼中继窃取——chalk/debug 事件中连 TOTP 都被钓走,故社区转向 passkey |
| passkey / WebAuthn | 基于公私钥对、绑定站点 Origin 的抗钓鱼登录凭证;钓鱼站点拿不到可重放的凭证 |
| OIDC(OpenID Connect) | 基于 OAuth2 的身份联合协议。npm/PyPI 的 trusted publishing 用它在 CI 中换取短时效发布凭证,避免在 CI 中存放长效令牌 |
| trusted publishing | npm/PyPI 的"可信发布"机制总称:发布凭证由 OIDC 短时效签发、绑定指定仓库与工作流,而非长期令牌 |
| attestation(PEP 740) | PyPI 的"数字证明":随上传产物附带的签名声明(谁、在哪条流水线、如何构建),可被消费端验证 |
| provenance(来源证明) | 泛指"产物出自哪条可信流水线"的密码学证明;npm 2023-04 上线基于 Sigstore 的发布 provenance,内容标准由 SLSA 定义 |
| Sigstore / cosign | Linux 基金会旗下的制品签名与透明日志体系,为"可验证的来源"提供基础设施 |
| SLSA(Supply-chain Levels for Software Artifacts) | 构建完整性分级框架(构建轨道 L1–L3),核心要求是可信构建平台 + 隔离 + 产出可验证 provenance,现为 v1.2 |
| egress(出网)遥测 | 对构建/CI 节点对外网络连接的记录与告警;tj-actions 事件即由 StepSecurity Harden-Runner 的 egress 遥测发现 |
| policy-as-code | 把"只允许带有效签名/provenance 的制品进入下一环节"这类策略写成可自动执行的校验,在引入点强制执行 |
| hermetic build(密封构建) | 构建过程除声明输入外不接触网络与外部状态,使"产物 = 输入的确定性函数",是构建投毒防御的基石 |
| typosquatting | 抢注与热门包名形近的包名(如 crossenv 仿 cross-env)诱骗安装 |
| wiper | 毁盘型破坏载荷;TanStack 事件中"令牌被吊销即 rm -rf ~/"的守护进程即属此类 |
四、参考来源
以下链接合并自两份章节稿并去重,按主题分组:
理论与早期事件(1984–2019)
- Thompson (1984)《Reflections on Trusting Trust》:https://dl.acm.org/doi/10.1145/358198.358210
- XcodeGhost:https://threatpost.com/xcodeghost-ios-malware-contained/114745/
- left-pad:https://thenewstack.io/the-kik-kerfuffle/
- crossenv:https://blog.npmjs.org/post/163723642530/crossenv-malware-on-the-npm-registry
- eslint-scope 事后分析:https://eslint.org/blog/2018/07/postmortem-for-malicious-package-publishes/
- event-stream 取证:https://jaydenseric.com/blog/event-stream-compromise
- PEAR:https://thehackernews.com/2019/01/php-pear-hacked.html / https://www.helpnetsecurity.com/2019/01/24/php-pear-compromise/
国家级警报与命名之年(2020–2021)
- GitHub 收购 npm:https://github.blog/2020-03-16-npm-is-joining-github/
- SolarWinds:https://cloud.google.com/blog/topics/threat-intelligence/evasive-attacker-leverages-solarwinds-supply-chain-compromises-with-sunburst-backdoor / https://www.solarwinds.com/blog/new-findings-from-our-investigation-of-sunburst / https://www.cisa.gov/news-events/cybersecurity-advisories/aa20-352a
- 依赖混淆(Birsan 原文):https://medium.com/@alex.birsan/dependency-confusion-how-i-hacked-into-apple-microsoft-and-dozens-of-other-companies-4a5d60fec610
- Codecov:https://about.codecov.io/security-update / https://about.codecov.io/apr-2021-post-mortem
- EO 14028:https://www.nist.gov/itl/executive-order-14028-improving-nations-cybersecurity
- ua-parser-js:https://www.cisa.gov/news-events/alerts/2021/10/22/malware-discovered-popular-npm-package-ua-parser-js / https://www.sonatype.com/blog/npm-project-used-by-millions-hijacked-in-supply-chain-attack / https://cloud.google.com/blog/topics/threat-intelligence/supply-chain-node-js
- coa/rc:https://therecord.media/malware-found-in-coa-and-rc-two-npm-packages-with-23m-weekly-downloads / https://www.rapid7.com/blog/post/2021/11/05/new-npm-library-hijacks-coa-and-rc/
投毒工业化与防御成形(2022–2023)
- node-ipc/peacenotwar:https://snyk.io/blog/peacenotwar-malicious-npm-node-ipc-package-vulnerability/
- PyPI ctx:https://www.sonatype.com/blog/pypi-package-ctx-compromised-are-you-at-risk / https://www.crowdstrike.com/en-us/blog/how-crowdstrike-detects-poisoned-python-packages-ctx-phpass/
- torchtriton:https://github.com/pytorch/pytorch/issues/102439
- SLSA:https://slsa.dev / https://slsa.dev/spec/v1.2/faq
社会工程登顶(2024)
- XZ Utils:https://www.openwall.com/lists/oss-security/2024/03/29/4 / https://guardsix.com/blog/emerging-threats/xz-utils-backdoor / https://www.akamai.com/blog/security-research/critical-linux-backdoor-xz-utils-discovered-what-to-know / https://en.wikipedia.org/wiki/XZ_Utils_backdoor
- polyfill.io:https://www.sonatype.com/blog/polyfill.io-supply-chain-attack-hits-100000-websites-all-you-need-to-know / https://fossa.com/blog/polyfill-supply-chain-attack-details-fixes/
- PyPI attestation:https://blog.pypi.org/posts/2024-11-14-pypi-now-supports-digital-attestations/
蠕虫元年(2025)
- Nx s1ngularity:https://www.wiz.io/blog/s1ngularity-supply-chain-attack
- chalk/debug:https://www.wiz.io/blog/widespread-npm-supply-chain-attack-breaking-down-impact-scope-across-debug-chalk / https://www.aikido.dev/blog/npm-debug-and-chalk-packages-compromised / https://jfrog.com/blog/new-compromised-packages-in-largest-npm-attack-in-history / https://www.paloaltonetworks.com/blog/cloud-security/npm-supply-chain-attack
- Shai-Hulud:https://www.cisa.gov/news-events/alerts/2025/09/23/widespread-supply-chain-compromise-impacting-npm-ecosystem / https://unit42.paloaltonetworks.com/npm-supply-chain-attack/ / https://www.truesec.com/hub/blog/500-npm-packages-compromised-in-ongoing-supply-chain-attack-shai-hulud / https://www.wiz.io/blog/shai-hulud-npm-supply-chain-attack
- npm 安全计划:https://github.blog/security/npm/our-plan-for-a-more-secure-npm-supply-chain/ / https://gbhackers.com/github-introduces-npm-security-with-stronger-authentication/
- npm token 政策:https://socket.dev/blog/npm-revokes-classic-tokens(站点抓取 403,事实来自搜索摘要)
- Shai-Hulud 2.0:https://www.stepsecurity.io/blog/sha1-hulud-the-second-coming-zapier-ens-domains-and-other-prominent-npm-packages-compromised / https://arcticwolf.com/resources/blog/shai-hulud-malware-targets-numerous-npm-packages-second-wave-npm-supply-chain-attack / https://securitylabs.datadoghq.com/articles/shai-hulud-2.0-npm-worm
- tj-actions:https://www.cisa.gov/news-events/alerts/2025/03/18/supply-chain-compromise-third-party-tj-actionschanged-files-cve-2025-30066-and-reviewdogaction / https://www.wiz.io/blog/github-action-tj-actions-changed-files-supply-chain-attack-cve-2025-30066 / https://github.com/advisories/ghsa-mrrh-fwg8-r2c3
蠕虫常态化(2026)
- axios / LiteLLM(Zscaler 直接抓取):https://www.zscaler.com/blogs/security-research/supply-chain-attacks-surge-march-2026
- axios 二手通告:https://securityboulevard.com/2026/03/technical-advisory-axios-npm-supply-chain-attack-cross-platform-rat-deployed-via-compromised-maintainer-account / https://www.infodivelabs.com/blog/axios-npm-supply-chain-attack
- Wiz Playbook:https://www.wiz.io/blog/the-supply-chain-attack-playbook-why-package-ecosystems-keep-getting-breached
- TanStack/Mini Shai-Hulud:https://www.wiz.io/blog/mini-shai-hulud-strikes-again-tanstack-more-npm-packages-compromised / https://snyk.io/blog/tanstack-npm-packages-compromised / https://openai.com/index/our-response-to-the-tanstack-npm-supply-chain-attack / https://thehackernews.com/2026/05/mini-shai-hulud-supply-chain-attack.html
- 微软 2026-05 披露(两条独立活动):https://www.microsoft.com/en-us/security/blog/2026/05/28/typosquatted-npm-packages-used-steal-cloud-ci-cd-secrets/ / https://www.microsoft.com/en-us/security/blog/2026/05/29/33-malicious-npm-packages-abuse-dependency-confusion-profile-developer-environments
- Red Hat RHSB-2026-006:https://access.redhat.com/security/vulnerabilities/RHSB-2026-006
- PyPI "Hades":https://checkmarx.com/blog/active-pypi-supply-chain-attack-26-packages-compromised/
- Sonatype 2026 年度报告:https://www.sonatype.com/state-of-the-software-supply-chain/2026/open-source-malware
- GitGuardian(Shai-Hulud npm/PyPI 记录):https://blog.gitguardian.com/shai-hulud-npm-pypi-supply-chain-attacks
修订补充检索(2026-10-31,审读意见落实时新增)
- @redhat-cloud-services 投毒:https://www.stepsecurity.io/blog/multiple-redhat-cloud-services-npm-packages-compromised / https://www.securityweek.com/supply-chain-attack-hits-32-red-hat-npm-packages
- Unit 42 npm 威胁图景分析:https://unit42.paloaltonetworks.com/monitoring-npm-supply-chain-attacks
- ChainDrop 蠕虫(keyv/cacheable 波次):https://www.zscaler.com/blogs/security-research/chaindrop-npm-worm
- OMB M-26-05 备忘录:https://www.whitehouse.gov/wp-content/uploads/2026/01/M-26-05-Adopting-a-Risk-based-Approach-to-Software-and-Hardware-Security.pdf
- npm 2027 年 1 月移除 2FA-bypass granular token 直接发布:https://github.com/orgs/community/discussions/201329
- Socket C 轮融资公告:https://socket.dev/blog/series-c
- PyPI 钓鱼官方通告(用于 2023-09 条目的对照说明):https://blog.pypi.org/posts/2025-07-28-pypi-phishing-attack