Skip to content

参考

基于 npm 官方文档(docs.npmjs.com)+ pnpm Supply Chain Security + MDN SRI + SLSA v1.0 spec + CycloneDX 1.7 + IBM audit-ci 编写,对照 npm CLI v10 / pnpm v10+ 稳定版

速查

  • 三条主线:消费端(lockfile / npm ci / ignore-scripts / npm audit / .npmrc / lockfile-lint / SRI)+ 发布端npm publish --provenance / Sigstore / SLSA / SBOM)+ 架构层(私有 scope 锁定防 dependency confusion)
  • 安装命令:CI 用 npm ci(不可改 lockfile)/ pnpm install --frozen-lockfile;lockfile 必须提交版本库
  • npm audit:--audit-level=low/moderate/high/critical只改阈值不过滤报告);fix --force 允许 SemVer major 跳变(危险)
  • npm audit signatures:registry signatures(ECDSA,所有包都有)vs attestations(带 provenance 的包才有)
  • SRI:<script integrity="sha256-... sha384-..." crossorigin="anonymous">,空格分隔多 hash,浏览器选最强算法
  • SLSA 三级:L1 provenance 存在 / L2 托管签名 / L3 构建隔离
  • CycloneDX vs SPDX:CycloneDX(ECMA-424,原生 VEX)/ SPDX(ISO 5962:2021,许可证合规强)
  • 关键默认:strict-ssl=true(默认,别关)/ ignore-scripts=false(npm 默认开脚本)
  • .npmrc 优先级:命令行 > npm_config_* > 项目 > 用户 > 全局 > 内置
  • 完整说明见 入门 / 核心防护实践

防护层级完整表

消费端

工具 / 做法命令示例防什么
lockfile 锁定npm cinpm ci依赖树漂移、lockfile 被悄悄篡改
lockfile 锁定(pnpm)pnpm install --frozen-lockfilepnpm install --frozen-lockfile同上
禁脚本(npm).npmrc ignore-scripts=truenpm config set ignore-scripts truepostinstall 投毒
禁脚本(pnpm)默认禁 + onlyBuiltDependencies/allowBuilds 白名单pnpm-workspace.yaml同上,且保留可信构建
CVE 扫描npm audit --audit-level=highnpm audit --audit-level=high已知漏洞进入依赖树
CVE 扫描(精细化)audit-ciaudit-ci --config .audit-ci.jsonc含 allowlist + expiry
lockfile-lintnpx lockfile-lint--allowed-hosts npm yarn --validate-httpslockfile 注入非预期 host
SRIHTML integrity + crossorigin<script integrity="sha384-..." crossorigin="anonymous">CDN 资源被替换
.npmrcstrict-ssl/@scope:registry=/cafile.npmrcMITM / dependency confusion
sigstore 验证npm audit signaturesnpm audit signatures包来源可验证

发布端

工具 / 做法命令示例防什么
provenancenpm publish --provenancenpm publish --provenance下游可验证「这包从这条 CI 出来」
SLSA 等级L1 → L2 → L3配置 CI 满足各级要求量化构建可信度
SigstoreFulcio CA + Rekor + Cosign自动通过 OIDCkeyless 签名
SBOM 归档@cyclonedx/cyclonedx-npm--output-file bom.json合规 + 反查 CVE 组件

架构层

工具 / 做法防什么
私有 scope 锁定.npmrc @mycorp:registry=dependency confusion
同名包抢注公共 registry 占位dependency confusion
virtual registryArtifactory / Nexus / CodeArtifact 查找顺序dependency confusion

工具命令清单

npm

bash
# CI 安装(确定性,需 lockfile,不可改)
npm ci

# 审计
npm audit                          # 列全部
npm audit --audit-level=high       # high 以上 exit 非零
npm audit --omit=dev               # 排除 devDependencies
npm audit fix                      # 自动升级(不破 SemVer)
npm audit fix --dry-run            # 预览变更(推荐先看)
npm audit fix --force              # ⚠️ 允许 major 跳变
npm audit signatures               # 验证签名 + provenance

# 发布
npm publish --provenance           # 启用 provenance
npm publish --provenance --access public

pnpm

bash
# CI 安装
pnpm install --frozen-lockfile

# 审计(pnpm v9+ 自带)
pnpm audit --audit-level=high

pnpm-workspace.yaml 关键配置

yaml
# 白名单允许跑构建脚本的依赖(v10 字段名)
onlyBuiltDependencies:
  - esbuild
  - swc
  - prisma
# v11 起改名为 allowBuilds:
# allowBuilds: [esbuild, swc, prisma]

# 默认延迟引入新版本(v11 默认 1440 分钟 = 1 天)
minimumReleaseAge: 1440

# 阻止信任等级降低的版本
trustPolicy: no-downgrade

# 阻止外来 URL 子依赖
blockExoticSubdeps: true

# 强制传递依赖版本(临时止血)
overrides:
  lodash: 4.17.21

SRI 生成

bash
# 命令行(openssl)
cat lib.js | openssl dgst -sha384 -binary | openssl base64 -A
# 输出:sha384-<base64hash>

# 或在线工具:https://www.srihash.org/

CycloneDX SBOM

bash
npx @cyclonedx/cyclonedx-npm \
  --output-file bom.json \
  --output-format JSON \
  --spec-version 1.5

lockfile-lint

bash
npx lockfile-lint --path package-lock.json --type npm \
  --allowed-hosts npm yarn --validate-https

audit-ci 配置(.audit-ci.jsonc

json
{
  "moderate": true,
  "allowlist": [
    "axios",
    "GHSA-xxxx-xxxx-xxxx",
    "pkg>pkg>pkg"
  ]
}

SRI 语法完整表

元素属性示例
<script>integrity + crossorigin<script src="cdn" integrity="sha384-..." crossorigin="anonymous">
<link>integrity + crossorigin<link rel="stylesheet" href="cdn" integrity="sha384-..." crossorigin="anonymous">

关键规则

  • 空格分隔多 hash:integrity="sha256-... sha384-... sha512-..."
  • 浏览器选最强算法(SHA-256 < 384 < 512)
  • 同算法多 hash:任一匹配即通过
  • 完全不匹配 → 返回网络错误,阻止执行
  • crossorigin="anonymous" 强制(防 XS-Leak),CDN 需返回 Access-Control-Allow-Origin

HTTP 层Integrity-Policy: blocked-destinations=(script), endpoints=(...) 强制 SRI。

npm audit signatures 输出

Verified 52 signatures and 12 attestations in 1247 packages
类别含义
registry signatures(ECDSA)所有包都有,由 npm registry 签发
attestations(带 provenance 的包才有)npm publish --provenance 发布的包才会被验证

audit-ci allowlist 精度

精度写法含义
module"axios"该包所有漏洞豁免(不含传递依赖
advisory"GHSA-xxxx-xxxx-xxxx"按 GHSA ID 精确豁免
path"pkg>pkg>pkg"* 通配按依赖链路精确豁免

NSPRecord 对象

json
{
  "active": true,
  "expiry": "2026-12-31",
  "notes": "等待上游 X 修复,预计 Q4 发版"
}

SLSA Build L0-L3

级别要求实践
L1provenance 存在(可未签名)任何 CI 输出
L2托管平台生成并签名 provenanceGitHub Actions / GitLab CI 自动满足
L3构建平台硬隔离防篡改,签名密钥对构建步骤不可见需隔离构建机 + 参数化

npm publish --provenance 把包从 L1 提到 L2(GitHub Actions 是托管平台自动签名)。

Sigstore 三组件

组件作用
Fulcio CA基于 OIDC token 签发短期临时证书(keyless 核心)
Rekor不可篡改的透明日志账本(公开可审计)
Cosign / CLI签名 / 验证工具

keyless 原理:用 OIDC 身份(GitHub Actions / GitLab CI 的 short-lived token)替代长期密钥,验证方查透明日志确认签名发生过。

CycloneDX vs SPDX

维度CycloneDXSPDX
标准Ecma TC54 / ECMA-424Linux Foundation / ISO/IEC 5962:2021
VEX原生内嵌走单独 profile
依赖图完整较弱
CI/CD 性能优化较重
起点强项漏洞管理许可证合规
当前版本1.7(2025-10-21,ECMA-424)2.4

.npmrc 配置完整表

配置作用默认
ignore-scripts=true禁 lifecycle 脚本false(npm 默认开脚本)
strict-ssl=true强制 HTTPS 验证true(默认,别关)
registry=默认 registryhttps://registry.npmjs.org/
@scope:registry=把 scope 锁到私有 registry-
always-auth每次请求都带认证false
//host/:_authToken=鉴权 token-
cafile=自定义 CA 证书路径-
provenance=true发布时启用 provenancefalse
unsafe-permroot 时以 root 跑脚本root 默认 false,非 root true

配置优先级链(高 → 低):命令行 flag > npm_config_* 环境变量 > 项目 .npmrc > 用户 ~/.npmrc > 全局 $PREFIX/etc/npmrc > 内置默认。

版本与生态(2026-07)

取值
npm CLI 主流版本v10
provenance 起始版本npm 9.5.0+(要求 GitHub Actions / GitLab 云端托管 runner,不支持自托管)
npm scripts lifecyclev7+ 已稳定,prepare 在 v7+ 改为后台运行,需 --foreground-scripts
pnpm 默认禁 postinstallv10 起(2025)
pnpm allowBuilds + minimumReleaseAge 默认v11 起(默认 minimumReleaseAge=1440 分钟即 1 天)
CycloneDX 当前版本1.7(ECMA-424,2025-10-21 发布);1.5/1.6 在工具链最常见
SLSA specv1.0 稳定(Build track L0-L3)

官方资源