npm 供应链攻击:为何频发以及如何防御

发布日期:2026-05-18 10:35:06   浏览量 :0
发布日期:2026-05-18 10:35:06  
0

2026西湖龙井茶官网DTC发售:茶农直供,政府溯源防伪到农户家 

每隔几个月,就会有一个新的 npm 软件包被劫持,向任何运行 npm install 的用户分发恶意软件,如此循环往复。2021 年 10 月的 ua-parser-js 遭入侵事件。2022 年的 node-ipc 抗议软件事件。反复出现的域名抢注(typosquatting)攻击。维护者账户通过网络钓鱼或过期域名被接管。在 r/programming 论坛上的反应总是一成不变:无法防止这种情况发生,说这话的恰恰是唯一无法防止此类情况的软件包管理器。

我们深入研究了真正驱动这些事件的因素,以及当今交付 JavaScript 的团队可以采取哪些切实可行的防御措施。

攻击背后的模式

这些攻击如出一辙。维护者的 npm 账户被攻破——可能是通过泄露的令牌、重复使用的密码,或者在其电子邮件域名过期后账户被接管。新版本包含一个安装后脚本,用于窃取环境变量、植入加密货币挖矿程序或安装远程 shell。等到被标记时,由于持续集成(CI)系统在每次拉取请求(PR)时都会运行 npm install,下载量已经高达数十万次。

2021 年的 ua-parser-js 事件就是一个典型模板。三个恶意版本(0.7.29、0.8.0、1.0.0)在同一周内发布。在维护者推送合法版本后的几小时内,攻击者就推送了嵌有加密货币挖矿程序的版本。npm 是在用户提醒维护者后才撤下这些版本——而非通过自动检测。任何将版本范围宽松锁定(^0.7.x)并在那段时间内运行 npm install 的用户都中招了。

2022 年的 colors.jsfaker.js 事件则有所不同——结果相同,但动机不同。维护者因不满那些从不付费或贡献的企业用户,亲自破坏了自己的软件包。导入时陷入无限循环。数千万的周下载量受到影响。供应链并不关心攻击者是怀有敌意还是仅仅因为倦怠。

2018 年的 event-stream 事件至今仍让人心有余悸。一位新维护者出于善意加入,却发布了一个针对特定加密货币钱包的后门,且数月未被发现。那次攻击既不是拼写错误也不是账户接管——而是社会工程学攻击。信任模型假设维护者会一直保持其身份。

为何 npm 特别容易受到攻击

三个结构性选择使得 npm 比 pip、RubyGems 或 Cargo 更容易成为攻击目标。

默认运行安装后脚本。 任何软件包都可以声明一个 postinstall 钩子,在安装时执行任意 Node 代码。Python 的 pip 会为源码分发包运行 setup.py,但趋势已强烈转向不包含代码执行的 wheel 包。Cargo 在执行 cargo add 时不会运行任意代码。而 npm 会在每台机器上的每次安装中执行代码——包括那些在环境变量中持有部署密钥的 CI 运行器。

传递依赖的深度。 一个典型的 Express 应用会引入 800 到 1,500 个传递依赖包。一个 Next.js 项目会引入 1,500 到 3,000 个。每一个依赖包都来自你从未谋面的维护者,构成了你无法手动审计的攻击面。相比之下,Go 项目的标准库涵盖了 npm 软件包处理的大部分功能,且模块依赖图保持较浅层级。

无权限限制发布。 任何人都可以注册未占用的名称、发布拼写近似包(typosquat),或复活被废弃的命名空间。crossenv 针对 cross-env 的拼写近似包在被下架前运行了两周。类似的仿冒包已被用于攻击 node-fetchchalk 和其他前 100 名热门软件包。

如果你的 CI 系统在每次拉取请求(PR)时运行的是 npm install(而不是针对锁定文件运行 npm ci),那么每一层级的每个依赖项都可能执行

免责声明:本文内容来自互联网,该文观点不代表本站观点。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请到页面底部单击反馈,一经查实,本站将立刻删除。

关于我们
热门推荐
合作伙伴
免责声明:本站部分资讯来源于网络,如有侵权请及时联系客服,我们将尽快处理
支持 反馈 订阅 数据
回到顶部