Hotdry.

Article

NPM v12 破坏性变更清单与迁移策略:脚本权限、Git 依赖与 CI/CD 适配

NPM v12 将默认禁用依赖脚本执行、Git 与远程依赖解析。本文提供迁移检查清单、approve-scripts 工作流及 CI/CD 配置方案,确保平滑升级。

2026-06-10web

NPM v12 预计于 2026 年 7 月发布,此次版本升级标志着包管理器安全模型的根本性转变。与以往的增量改进不同,v12 引入了 ** 显式许可(opt-in)** 机制,将原本自动执行的安装行为转变为需要开发者明确授权的操作。这一变化直接影响 npm install 的默认行为,涉及生命周期脚本执行、Git 依赖解析以及远程 tarball 获取三大核心场景。

三大破坏性变更详解

1. allowScripts 默认关闭:生命周期脚本执行受限

在 v12 中,allowScripts 配置项的默认值从 true 变更为 false。这意味着 preinstallinstallpostinstall 脚本将不再自动执行。值得注意的是,这一限制同样适用于隐式脚本—— 即使某个依赖包没有显式定义安装脚本,只要包含 binding.gyp 文件,npm 会自动触发 node-gyp rebuild,而这类隐式构建在 v12 中同样会被阻断。

此外,来自 Git、本地文件和符号链接依赖的 prepare 脚本也将受到同样的限制。这一变更直接回应了供应链攻击中常见的恶意脚本注入问题,但也意味着大量依赖原生模块的项目需要重新审视其安装流程。

2. --allow-git 默认 none:Git 依赖解析被禁用

Git 依赖(包括直接依赖和传递依赖)在 v12 中将默认被禁止解析。GitHub 指出,这一变更是为了关闭一个潜在的安全漏洞:恶意 Git 依赖可以通过 .npmrc 文件覆盖 Git 可执行路径,即使在 --ignore-scripts 模式下仍可能触发代码执行。

对于使用私有 Git 仓库或特定分支 / 标签作为依赖来源的项目,这需要在安装命令中显式添加 --allow-git 标志,或在配置文件中调整默认行为。

3. --allow-remote 默认 none:远程 URL 依赖受限

通过 HTTPS URL 直接引用的 tarball 依赖(如 https://example.com/package.tgz)在 v12 中也将默认被阻止。这一限制同样适用于传递依赖链中的远程 URL 引用。相比之下,--allow-file--allow-directory 标志的默认行为在 v12 中保持不变,本地文件系统依赖不受影响。

迁移策略:从审计到审批的工作流

NPM 团队已在 v11.16.0 及更高版本中提供了警告模式,允许开发者在正式升级前评估影响范围。建议按以下步骤执行迁移:

步骤一:审计当前依赖脚本

将本地 npm 升级至 11.16.0 或更高版本,执行常规安装命令并观察警告输出。使用以下命令查看哪些包的脚本将被阻断:

npm approve-scripts --allow-scripts-pending

该命令会列出所有待审批的脚本及其所属包,包括生命周期脚本的类型(preinstall/install/postinstall)和触发条件。

步骤二:建立信任清单

基于审计结果,对可信包执行审批:

# 审批特定包的脚本执行权限
npm approve-scripts <package-name>

# 拒绝不可信包的脚本执行
npm deny-scripts <package-name>

审批结果将自动写入 package.jsontrustedDependencies 字段(或类似配置结构),该清单应提交至版本控制,确保团队成员和 CI 环境使用一致的权限策略。

步骤三:处理原生模块依赖

对于依赖 node-gyp 构建的包(如 SQLite、Sharp、bcrypt 等),需要评估两种方案:

  1. 审批脚本执行:如果信任该包及其构建流程,将其加入允许清单
  2. 预构建二进制包:优先选择提供预编译二进制文件的版本,避免构建步骤

对于后者,可以检查包是否提供 prebuilt 版本,或通过 npm config set python 等配置确保构建环境就绪后再手动触发安装。

CI/CD 适配方案

Lockfile 兼容性

NPM v12 的权限变更不会影响 package-lock.json 的结构,但可能导致安装失败。建议在升级前执行以下检查:

  1. 在 CI 环境中使用 npm 11.16.0+ 运行安装,确认无警告
  2. 验证 package.json 中的信任清单已同步至仓库
  3. 对于使用 Git 依赖的项目,在 CI 脚本中显式添加 --allow-git 标志

环境配置模板

针对不同场景的 CI 配置建议:

# 标准项目(无 Git/远程依赖)
npm ci

# 包含 Git 依赖的项目
npm ci --allow-git

# 包含远程 tarball 依赖的项目
npm ci --allow-git --allow-remote

# 需要特定脚本权限的项目(配合信任清单)
npm ci --allow-scripts

注意:--allow-scripts 标志在 v12 中行为发生变化 —— 它不再全局启用脚本执行,而是与 package.json 中的信任清单配合使用,仅执行已审批的脚本。

回滚策略

在团队级升级过程中,建议保留 npm v11 的容器镜像或锁定版本,以便在遭遇未预期阻断时快速回退。可以在 CI 配置中通过环境变量控制 npm 版本:

# GitHub Actions 示例
- name: Setup Node.js
  uses: actions/setup-node@v4
  with:
    node-version: '22'
    # 显式指定 npm 版本,避免自动升级
    npm-version: '11.16.0'

总结与行动清单

NPM v12 的安全强化虽然增加了配置复杂度,但有效降低了供应链攻击面。对于维护者和团队负责人,建议按以下优先级执行准备:

  1. 立即行动:将开发环境 npm 升级至 11.16.0+,运行 npm approve-scripts --allow-scripts-pending 生成影响评估报告
  2. 本周内:审查并审批关键依赖的脚本权限,更新 package.json 信任清单并提交
  3. 升级前:在 staging 环境模拟 v12 行为,验证 CI/CD 管道兼容性
  4. 长期:评估 Git 依赖和远程 tarball 的必要性,优先迁移至 registry 发布的正式版本

这些变更已在 npm 11.16.0 中以警告形式提供预览,充分利用这一过渡期是确保生产环境平稳升级的关键。


资料来源

web

内容声明:本文无广告投放、无付费植入。

如有事实性问题,欢迎发送勘误至 i@hotdrydog.com