如何应对 npm 依赖供应链攻击的风险

文章分析了 npm 依赖供应链攻击的风险,指出攻击者可以通过篡改深层依赖项来影响用户,尤其是在 Web3 领域,前端直接处理交易签名,风险更高。文章建议通过减少依赖、自建核心模块、使用 IPFS CID 验证构建产物等方法来降低风险。

最新的 npm 泄露事件表明,依赖供应链深处的一个微小变化如何重写用户所见、签名和发送的内容。

一个警钟

2025 年 9 月 8 日,攻击者通过网络钓鱼攻击了一位知名的 npm 维护者,并推送了 18 个软件包的恶意版本,包括 chalkdebug——总共代表了每周 数十亿次 的下载量。该有效载荷Hook了浏览器 API ( fetchXMLHttpRequestwindow.ethereum 等) 以 拦截钱包交互并重写支付目的地,在此过程中劫持资金。安全公司媒体 将入侵追溯到一个极具说服力的“npm support”仿冒域名,并 记录 了 drainer 的行为。

对于防御者来说,有两点很重要:

  1. 通过传递依赖的爆炸半径。 许多应用程序并非直接拉取恶意代码,而是因为其他东西依赖于它。
  2. 目标是浏览器和钱包。 该恶意软件在客户端运行,并专注于 web3 流程——这正是 DApp 可能损失真金白银的地方。

为什么“仅仅审查你的依赖”在 JS 中是一种幻想

传递深度和数量

在 Node/JS 中,大多数风险是 间接 隐藏的。Snyk 报告称, 大约 86% 的 Node.js 漏洞出现在传递依赖中,而不是你自己选择的依赖项。这是你在代码审查中看不到的部分。

多个副本,多个版本

Node 的解析器很乐意安装同一库的 多个 版本,以满足冲突的范围。npm 有一个 dedupe 命令和一个 --prefer-dedupe 开关,但默认设置通常 favore 更的版本——即使这增加了重复。在实践中,你会发布一个包含多个 ansi-* 变体的捆绑包,每个变体都有自己的更新和风险状况。

覆盖子依赖项是可能的,但很脆弱

现代 npm 支持 "overrides",以强制在整个图中使用嵌套的 依赖项 的单个版本,但团队仍然报告了尖锐的边缘。你 可以 在任何地方固定 ansi-regex,但你现在正在自己维护树的一部分。

Registry ≠ repository

你从 registry 安装的 package 不需要与你略读的 GitHub repo 匹配。攻击者利用了这个差距。

所有这些使得“验证每个依赖项”更接近于一个研究项目,而不是一个构建步骤。

Dev dependencies 确实 重要:攻击者针对 开发人员****

devDependencies 视为生产级别的风险。攻击者喜欢它们,因为它们会进入你的笔记本电脑、你的 CI 和你的Token。

ESLint compromise (2018)

恶意的 @nx/* 版本在 macOS/Linux 上运行了一个 post-install 脚本,该脚本收集了 SSH 密钥、npm/GitHub Token、.env 文件和钱包,然后使用 AI CLI 工具 (Claude, Gemini) 进行侦察和数据泄露——在受害者的 GitHub 帐户中创建一个“s1ngularity-repository”。这是开发工具作为 一切 的入口点。

eslint-config-prettier 和朋友 (2025 年 7 月)

网络钓鱼导致了流行的 lint/format 软件包的 恶意版本——再次,是面向开发人员的组件。

当开发工具变坏时,会发生两件事:你会丢失密钥,并且你的 前端构建 可能会被污染——导致面向用户的泄露。

Web3 的转折:前端签署金钱

加密货币用户不仅仅是阅读你的网站;他们还会 从你的网站签署交易。这就是为什么攻击不断围绕钱包展开的原因:

event-stream → Copay (2018)** ](https://es-incident.github.io/paper.html) 在特定版本之间的构建中窃取密钥。

ua-parser-js (2021) ](https://github.com/okcontract/cells) 是一个核心库的示例,它的设计 没有外部运行时依赖项**。更少的移动部件意味着恶意软件可以进入的地方更少。

  1. Monorepo + 可重现的构建 一个地方进行审计,一个地方锁定版本,一个地方强制执行 provenance。
  2. 将 artifacts 部署到 IPFS ; 将 CID 视为信任根。 CID 是按内容寻址的:更改一个字节,你将获得一个不同的 CID。用户、合作伙伴或审核人员可以固定并验证我们发布的准确内容。“给定 CID ⇒ 内容”是该模型。** ](https://pnpm.io/settings)/yarn)。保留一个你审核的 override 短名单。

关闭 install-time 的意外

  • 在 CI 和构建服务器上, 设置 NPM_CONFIG_IGNORE_SCRIPTS=true 并运行 npm ci。这 阻止 preinstall/postinstall Hook——这是在几个开发工具泄露中使用的向量。(如果你确实需要脚本,则按软件包选择加入。)

降低 registry 风险

  • registry 内容视为权威内容,而不是 GitHub repo; 验证 将要安装的准确 tarball
  • 供应商化或镜像化你离不开的少量运行时库。对于其他一切,最好使用你自己的代码。

提高你发布的内容的标准

发布可以 验证 的东西

  • 将你的 构建 artifacts 发布到 IPFS 并传达用户应该固定的 CID。内容寻址意味着任何人都可以检查他们是否获得了你批准的 完全相同的位

将“NIH”作为一种安全控制

嘲笑重建小型实用程序的文化将我们推向了庞大的图中,在这些图中,维护人员糟糕的一天——或者一次网络钓鱼——可能会变成你用户的钱包被掏空。9 月 8 日对 chalk / debug 的攻击表明,对手需要破坏 DApp 的 前端钱包流程 的代码是多么的少。退回到更少的依赖项,自己编写核心构建块(如 cells),以及用 可验证的 artifacts(IPFS CIDs,provenance)标记 releases 不是纯粹主义;而是风险管理。

  • 原文链接: blog.blockmagnates.com/n...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
blockmagnates
blockmagnates
The New Crypto Publication on The Block