npm-supply-chain-audit

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

npm supply-chain security audit

npm供应链安全审计

Audit the current repo for npm supply-chain security issues, present findings to the user, and apply fixes only after confirmation.
审计当前仓库中的npm供应链安全问题,向用户呈现检测结果,并仅在用户确认后应用修复。

Step 1 – Detect the package manager

步骤1 – 检测包管理器

Check which package manager(s) are in use:
  • package-lock.json
    -> npm
  • aube-lock.yaml
    -> Aube
  • pnpm-lock.yaml
    -> pnpm
  • yarn.lock
    +
    .yarnrc.yml
    -> Yarn Berry;
    yarn.lock
    without
    .yarnrc.yml
    -> Yarn Classic
  • bun.lockb
    or
    bun.lock
    -> Bun
  • packageManager
    field in
    package.json
    confirms the PM and version
Use the
packageManager
field to determine the version. If not present, run the PM's
--version
command. The version is needed for checks that depend on minimum PM versions (e.g. pnpm 10+, pnpm 11+, npm 11.10+, Yarn Berry 4.10+, Bun 1.3+).
pnpm 11 ships several supply-chain protections on by default (
minimumReleaseAge: 1440
,
blockExoticSubdeps: true
,
strictDepBuilds: true
) and only reads pnpm-specific settings from
pnpm-workspace.yaml
(or
~/.config/pnpm/config.yaml
), not from
.npmrc
. Many checks below differ between pnpm 10 and pnpm 11+.
If no lockfile exists, default to npm.
检查当前使用的包管理器:
  • package-lock.json
    -> npm
  • aube-lock.yaml
    -> Aube
  • pnpm-lock.yaml
    -> pnpm
  • yarn.lock
    +
    .yarnrc.yml
    -> Yarn Berry;无
    .yarnrc.yml
    yarn.lock
    -> Yarn Classic
  • bun.lockb
    bun.lock
    -> Bun
  • package.json
    中的
    packageManager
    字段可确认包管理器及其版本
使用
packageManager
字段确定版本。如果该字段不存在,运行包管理器的
--version
命令。版本信息对依赖最低版本的检查是必需的(例如pnpm 10+、pnpm 11+、npm 11.10+、Yarn Berry 4.10+、Bun 1.3+)。
pnpm 11默认启用多项供应链防护(
minimumReleaseAge: 1440
blockExoticSubdeps: true
strictDepBuilds: true
),且仅从
pnpm-workspace.yaml
(或
~/.config/pnpm/config.yaml
)读取pnpm特定设置,而非
.npmrc
。以下许多检查在pnpm 10和pnpm 11+之间存在差异。
如果不存在锁文件,默认使用npm。

Step 2 – Audit

步骤2 – 审计

Work through the checks below. For each one, check the current state and record whether it passes or needs a fix. Do NOT make any changes yet.
执行以下检查。对于每一项,检查当前状态并记录是否通过或需要修复。请勿进行任何修改

2.1 Lockfile committed

2.1 已提交锁文件

If no lockfile exists (
package-lock.json
,
pnpm-lock.yaml
,
yarn.lock
,
bun.lockb
,
bun.lock
,
aube-lock.yaml
), warn the user they should run their package manager's install command and commit the lockfile. Do NOT run install yourself.
如果不存在锁文件(
package-lock.json
pnpm-lock.yaml
yarn.lock
bun.lockb
bun.lock
aube-lock.yaml
),提醒用户应运行包管理器的install命令并提交锁文件。请勿自行运行install

2.2 Block lifecycle scripts

2.2 拦截生命周期脚本

npm – ensure
.npmrc
contains:
ini
ignore-scripts=true
pnpm 10+ – blocks lifecycle scripts by default. Check that
pnpm-workspace.yaml
does NOT set
dangerouslyAllowAllBuilds: true
. If it does, warn the user. pnpm 11+ additionally enables
strictDepBuilds: true
by default, so installs error (rather than just warn) when a dependency wants to run a build script that isn't in the allowlist – verify it has not been disabled in
pnpm-workspace.yaml
.
pnpm <= 9 – ensure
.npmrc
contains
ignore-scripts=true
.
Yarn Classic (v1) – ensure
.npmrc
contains
ignore-scripts=true
.
Yarn Berry (v2+) – ensure
.yarnrc.yml
contains:
yaml
enableScripts: false
Bun – blocks lifecycle scripts by default. No action needed.
Aube – blocks lifecycle scripts by default. Check that
aube-workspace.yaml
does NOT set
dangerouslyAllowAllBuilds: true
. If it does, warn the user.
npm – 确保
.npmrc
包含:
ini
ignore-scripts=true
pnpm 10+ – 默认拦截生命周期脚本。检查
pnpm-workspace.yaml
是否未设置
dangerouslyAllowAllBuilds: true
。如果已设置,提醒用户。pnpm 11+额外默认启用
strictDepBuilds: true
,因此当依赖想要运行不在允许列表中的构建脚本时,安装会报错(而非仅警告)——需验证该设置未在
pnpm-workspace.yaml
中被禁用。
pnpm <= 9 – 确保
.npmrc
包含
ignore-scripts=true
Yarn Classic (v1) – 确保
.npmrc
包含
ignore-scripts=true
Yarn Berry (v2+) – 确保
.yarnrc.yml
包含:
yaml
enableScripts: false
Bun – 默认拦截生命周期脚本。无需操作。
Aube – 默认拦截生命周期脚本。检查
aube-workspace.yaml
是否未设置
dangerouslyAllowAllBuilds: true
。如果已设置,提醒用户。

2.3 Build script allowlists

2.3 构建脚本允许列表

When lifecycle scripts are blocked, some packages legitimately need build scripts. Check the lockfile for packages that require builds:
  • pnpm – look for entries with
    requiresBuild: true
    in
    pnpm-lock.yaml
  • npm – look for
    hasInstallScript: true
    in
    package-lock.json
  • Yarn Berry – look for
    hasBin
    or build-related metadata in
    yarn.lock
  • Bun – check
    bun.lock
    for packages with lifecycle scripts
Compare the list of packages that require builds against the current allowlist. Report any that are missing, but do NOT suggest adding them blindly – the user must verify each package is trusted before allowlisting it. Only well-known packages from reputable maintainers (e.g.
esbuild
,
sharp
,
@swc/core
) should be considered.
The allowlist setting per package manager:
pnpm 11+
allowBuilds
map in
pnpm-workspace.yaml
. This replaces
onlyBuiltDependencies
,
onlyBuiltDependenciesFile
,
neverBuiltDependencies
, and
ignoredBuiltDependencies
, which are no longer supported:
yaml
allowBuilds:
  esbuild: true
  core-js: false
pnpm 10 / Aube
onlyBuiltDependencies
in
pnpm-workspace.yaml
/
aube-workspace.yaml
:
yaml
onlyBuiltDependencies:
  - esbuild
Yarn Berry
dependenciesMeta
in
package.json
:
json
"dependenciesMeta": {
  "esbuild": { "built": true }
}
Bun
trustedDependencies
in
package.json
:
json
"trustedDependencies": ["esbuild"]
当生命周期脚本被拦截时,部分包确实需要构建脚本。检查锁文件中需要构建的包:
  • pnpm – 在
    pnpm-lock.yaml
    中查找带有
    requiresBuild: true
    的条目
  • npm – 在
    package-lock.json
    中查找
    hasInstallScript: true
  • Yarn Berry – 在
    yarn.lock
    中查找
    hasBin
    或与构建相关的元数据
  • Bun – 在
    bun.lock
    中检查带有生命周期脚本的包
将需要构建的包列表与当前允许列表进行对比。报告任何缺失的包,但请勿盲目建议添加——用户必须先验证每个包是否可信,再将其加入允许列表。仅应考虑来自知名维护者的知名包(例如
esbuild
sharp
@swc/core
)。
各包管理器的允许列表设置:
pnpm 11+
pnpm-workspace.yaml
中的
allowBuilds
映射。该设置替代了不再受支持的
onlyBuiltDependencies
onlyBuiltDependenciesFile
neverBuiltDependencies
ignoredBuiltDependencies
yaml
allowBuilds:
  esbuild: true
  core-js: false
pnpm 10 / Aube
pnpm-workspace.yaml
/
aube-workspace.yaml
中的
onlyBuiltDependencies
yaml
onlyBuiltDependencies:
  - esbuild
Yarn Berry
package.json
中的
dependenciesMeta
json
"dependenciesMeta": {
  "esbuild": { "built": true }
}
Bun
package.json
中的
trustedDependencies
json
"trustedDependencies": ["esbuild"]

2.4 Release-age cooldown

2.4 发布冷却期

Check if a release-age cooldown is configured. If not, recommend adding one. If already configured, note the current value. When presenting findings, advise the user that 3 days is a good minimum. Mention that 7 days provides stronger protection but slows down updates.
The setting per package manager:
npm 11.10+
min-release-age
in
.npmrc
(value in days):
ini
min-release-age=3
pnpm 10.16+
minimumReleaseAge
in
pnpm-workspace.yaml
(value in minutes):
yaml
minimumReleaseAge: 4320
pnpm 11+ – defaults to
minimumReleaseAge: 1440
(1 day). The repo is already protected, but recommend overriding to a stronger value (e.g.
4320
for 3 days or
10080
for 7 days). Also verify the default has not been disabled with
minimumReleaseAge: 0
.
Also check if
.npmrc
contains a
minimumReleaseAge
setting – this is a common mistake. pnpm only reads this setting from
pnpm-workspace.yaml
, not
.npmrc
(and pnpm 11+ does not read any pnpm-specific settings from
.npmrc
at all). If found, warn the user and suggest moving it to
pnpm-workspace.yaml
.
Yarn Berry 4.10+
npmMinimalAgeGate
in
.yarnrc.yml
(value in minutes):
yaml
npmMinimalAgeGate: 4320
Bun 1.3+
minimumReleaseAge
in
bunfig.toml
(value in seconds):
toml
[install]
minimumReleaseAge = 259200
Aube – defaults to 1440 minutes (1 day).
minimumReleaseAge
in
aube-workspace.yaml
(value in minutes):
yaml
minimumReleaseAge: 4320
检查是否配置了发布冷却期。如果未配置,建议添加。如果已配置,记录当前值。呈现检测结果时,建议用户设置至少3天的冷却期。说明7天的冷却期防护更强,但会减慢更新速度。
各包管理器的设置:
npm 11.10+
.npmrc
中的
min-release-age
(单位:天):
ini
min-release-age=3
pnpm 10.16+
pnpm-workspace.yaml
中的
minimumReleaseAge
(单位:分钟):
yaml
minimumReleaseAge: 4320
pnpm 11+ – 默认设置为
minimumReleaseAge: 1440
(1天)。仓库已受防护,但建议覆盖为更强的设置(例如
4320
代表3天,
10080
代表7天)。同时验证默认设置未被
minimumReleaseAge: 0
禁用。
还要检查
.npmrc
是否包含
minimumReleaseAge
设置——这是常见错误。pnpm仅从
pnpm-workspace.yaml
读取该设置,而非
.npmrc
(且pnpm 11+完全不从
.npmrc
读取任何pnpm特定设置)。如果发现该设置,提醒用户并建议将其移至
pnpm-workspace.yaml
Yarn Berry 4.10+
.yarnrc.yml
中的
npmMinimalAgeGate
(单位:分钟):
yaml
npmMinimalAgeGate: 4320
Bun 1.3+
bunfig.toml
中的
minimumReleaseAge
(单位:秒):
toml
[install]
minimumReleaseAge = 259200
Aube – 默认设置为1440分钟(1天)。
aube-workspace.yaml
中的
minimumReleaseAge
(单位:分钟):
yaml
minimumReleaseAge: 4320

2.5 Block exotic subdeps (pnpm / Aube)

2.5 拦截外来子依赖(pnpm / Aube)

pnpm 10 – ensure
pnpm-workspace.yaml
contains:
yaml
blockExoticSubdeps: true
pnpm 11+ / Aube – defaults to true. Verify it has not been explicitly disabled in
pnpm-workspace.yaml
/
aube-workspace.yaml
.
This prevents transitive dependencies from using git or tarball URLs.
pnpm 10 – 确保
pnpm-workspace.yaml
包含:
yaml
blockExoticSubdeps: true
pnpm 11+ / Aube – 默认设置为true。验证该设置未在
pnpm-workspace.yaml
/
aube-workspace.yaml
中被显式禁用。
此设置可防止传递依赖使用git或tarball URL。

2.6 Trust policy (pnpm / Aube)

2.6 信任策略(pnpm / Aube)

pnpm / Aube – ensure
pnpm-workspace.yaml
or
aube-workspace.yaml
contains:
yaml
trustPolicy: no-downgrade
This blocks packages whose trust level has decreased.
pnpm / Aube – 确保
pnpm-workspace.yaml
aube-workspace.yaml
包含:
yaml
trustPolicy: no-downgrade
此设置可阻止信任级别降低的包。

2.7 Hardened mode (Yarn Berry only)

2.7 强化模式(仅Yarn Berry)

If using Yarn Berry, ensure
.yarnrc.yml
contains:
yaml
enableHardenedMode: true
This validates the lockfile against the registry.
如果使用Yarn Berry,确保
.yarnrc.yml
包含:
yaml
enableHardenedMode: true
此设置会验证锁文件与注册表的一致性。

2.8 Dependency update cooldown (Renovate / Dependabot)

2.8 依赖更新冷却期(Renovate / Dependabot)

Check if the repo uses Renovate or Dependabot and whether a cooldown is configured.
Renovate – look for config in
renovate.json
,
renovate.json5
,
.github/renovate.json
,
.github/renovate.json5
,
.renovaterc
,
.renovaterc.json
, or a
"renovate"
key in
package.json
. Check if the
extends
array includes any of the following (all of which include a 3-day npm cooldown):
  • "config:best-practices"
  • "security:minimumReleaseAgeNpm"
  • "NitorCreations/renovate-config:recommended"
    (the Nitor recommended preset extends
    config:best-practices
    )
Also check shared presets – if
extends
references another custom preset (e.g.
"local>myorg/renovate-config"
), note that the cooldown may already be configured there and the user should verify.
If Renovate config exists but doesn't include any of the above presets, suggest adding
security:minimumReleaseAgeNpm
:
json
{ "extends": ["security:minimumReleaseAgeNpm"] }
Dependabot – look for
.github/dependabot.yml
. Check if npm ecosystem entries have a
cooldown
configured. If not, suggest adding:
yaml
cooldown:
  default-days: 3
If neither Renovate nor Dependabot is configured, skip this check – don't add a dependency update tool unprompted.
检查仓库是否使用Renovate或Dependabot,以及是否配置了冷却期。
Renovate – 在
renovate.json
renovate.json5
.github/renovate.json
.github/renovate.json5
.renovaterc
.renovaterc.json
package.json
中的
"renovate"
键中查找配置。检查
extends
数组是否包含以下任一预设(均包含3天的npm冷却期):
  • "config:best-practices"
  • "security:minimumReleaseAgeNpm"
  • "NitorCreations/renovate-config:recommended"
    (Nitor推荐预设继承自
    config:best-practices
同时检查共享预设——如果
extends
引用了其他自定义预设(例如
"local>myorg/renovate-config"
),说明冷却期可能已在该预设中配置,用户需自行验证。
如果存在Renovate配置但未包含上述任一预设,建议添加
security:minimumReleaseAgeNpm
json
{ "extends": ["security:minimumReleaseAgeNpm"] }
Dependabot – 查找
.github/dependabot.yml
。检查npm生态系统条目是否配置了
cooldown
。如果未配置,建议添加:
yaml
cooldown:
  default-days: 3
如果未配置Renovate或Dependabot,跳过此检查——请勿未经提示添加依赖更新工具。

Step 3 – Present findings

步骤3 – 呈现检测结果

Present a summary of the audit results to the user:
  1. Start with a one-line summary count (e.g. "3 passing, 4 need fixes")
  2. List checks that already pass as bullet points (not numbered) – keep these brief
  3. List checks that need fixes, with the specific changes that would be made
  4. List any issues that require manual action (e.g. missing lockfile,
    dangerouslyAllowAllBuilds
    )
  5. When multiple fixes target the same file, show a combined preview of the full proposed file content at the end
  6. Do not use horizontal rules (
    ---
    ) – headings provide enough structure
IMPORTANT formatting rules – follow exactly:
  • Use a numbered list for fixes. Put ALL explanation BEFORE the code block.
  • Every proposed config change MUST be wrapped in a fenced code block using triple backticks and a language tag (e.g. yaml, json, toml, ini). RAW config text without triple-backtick fences is WRONG and hard to read.
  • Indent code blocks with 3 spaces so they are nested inside the list item. This is critical – without the indent, the code block breaks out of the list and the numbering restarts (causing duplicate numbers like 1, 1, 2, 2).
  • Leave a blank line before the opening triple backticks and after the closing triple backticks.
Then ask the user for confirmation before proceeding.
向用户呈现审计结果摘要:
  1. 开头用一行总结检测结果数量(例如“3项通过,4项需要修复”)
  2. 用无序列表列出已通过的检查——保持简洁
  3. 列出需要修复的检查,以及具体的修改方案
  4. 列出需要手动操作的问题(例如缺失锁文件、
    dangerouslyAllowAllBuilds
    设置)
  5. 当多个修复针对同一文件时,在末尾展示完整的拟修改文件内容预览
  6. 请勿使用水平分隔线(
    ---
    )——标题已提供足够的结构
重要格式规则——严格遵循:
  • 使用有序列表列出修复方案。所有说明文字需放在代码块之前
  • 所有拟议的配置修改必须用三重反引号和语言标签(例如yaml、json、toml、ini)包裹在代码块中。未使用三重反引号的原始配置文本是错误的,且难以阅读。
  • 代码块缩进3个空格,使其嵌套在列表项内。这一点至关重要——如果没有缩进,代码块会跳出列表,导致编号重新开始(出现1、1、2、2等重复编号)。
  • 在开头的三重反引号前和结尾的三重反引号后各留一个空行。
然后请求用户确认后再继续。

Step 4 – Apply fixes

步骤4 – 应用修复

After the user confirms, apply the agreed-upon changes. If the user wants to skip certain fixes, respect that. Summarize what was changed.
用户确认后,应用商定的修改。如果用户希望跳过某些修复,需尊重其选择。总结已修改的内容。