Cover Image for npm重大事件:如何保护项目免受供应链攻击
[npm][JavaScript][Security][SupplyChain][Node.js]
2025年8月12日

npm重大事件:如何保护项目免受供应链攻击

2025 年 7 月,npm 生态遭遇了其历史上最大规模的供应链攻击之一。攻击者获取了热门包维护者的账号访问权限,并发布了恶意版本,数以百万计的开发者在不知情的情况下安装了这些版本。

发生了什么

受影响的包:

攻击过程:

  1. 通过仿冒域名 npnjs.com 实施网络钓鱼 → 维护者输入了凭据。
  2. 攻击者获得访问权限并直接向 npm 发布恶意构建。
  3. 恶意代码伪装为 postinstall 脚本,下载 DLL 或开启 WebSocket 后门。
  4. 这些发布绕过了 GitHub 仓库——常规的提交监控不起作用。

总影响 — 每周超过 1.8 亿次下载。

来源:


如何防御类似攻击

1. 固定精确版本

package.json 中:

"eslint-config-prettier": "10.1.0"

不要这样:

"eslint-config-prettier": "^10.1.0"

让 npm 在今后的安装中默认保存精确版本的命令:

npm config set save-exact true

在仓库的 .npmrc 中还可以强制:

save-exact=true

如何快速为整个项目固定版本

如果你的 package.json 已经使用了 ^~,可以快速移除并改为精确版本。

npm:

npx npm-check-updates -f "/.*/" --removeRange --upgrade
  • npm-check-updates 是一个管理依赖版本的工具。
  • --removeRange 会从所有条目中移除 ^~

npm-check-updates 并不读取 package-lock.json。它只操作 package.json,将依赖版本替换为 npm 上的最新版本(可按你的过滤条件和限制)。如果你在仓库中提交了 package-lock.json,更安全的做法是直接根据 lockfile 固定版本。这里有一个可用的 Node.js 脚本,可以从 package-lock.json 读取精确版本并写入 package.json(且不含 ^~)。

2. 使用 lockfile

package-lock.json 提交到仓库。这样可以固定所有依赖(包括传递依赖)。

3. 启用依赖审计

  • npm audit

4. 尽量减少 postinstall 脚本

除非绝对必要,避免使用在安装阶段执行代码的依赖。

5. 为 npm 账号开启双重验证(2FA)

即便密码泄露,也能显著降低被接管风险。

6. 核对邮件与域名

不要直接点击“官方”邮件中的链接,先核对地址。npmjs.comnpnjs.com 只差一个字母。


结语

供应链攻击愈发频繁,即便是历史悠久的热门包也可能遭到入侵。减少自动更新、管控依赖并保持警惕,是保护项目的关键步骤。

继续阅读

加入我们的社区