npm-audit

运行安全审计

选择 CLI 版本

概述

npm audit [fix|signatures]

描述

audit 命令将项目中配置的依赖项的描述提交到默认注册表,并请求已知漏洞的报告。如果发现任何漏洞,则会计算影响和相应的修复措施。如果提供了 fix 参数,则会将修复措施应用于包树。

如果未发现漏洞,则命令将以 0 退出代码退出。

请注意,某些漏洞无法自动修复,需要手动干预或审查。另请注意,由于 npm audit fix 在幕后运行完整的 npm install,所有适用于安装程序的配置也适用于 npm install - 因此,诸如 npm audit fix --package-lock-only 之类的内容将按预期工作。

默认情况下,如果发现任何漏洞,audit 命令将以非零代码退出。在 CI 环境中,包含 --audit-level 参数以指定导致命令失败的最低漏洞级别可能很有用。此选项不会过滤报告输出,它只是更改命令的失败阈值。

包锁定

默认情况下,npm 要求使用 package-lock 或 shrinkwrap 才能运行 audit。可以使用 --no-package-lock 绕过包锁定,但请注意,结果每次运行可能会有所不同,因为 npm 会每次重建依赖项树。

审计签名

为了确保从公共 npm 注册表或任何支持签名的注册表下载的包的完整性,可以使用 npm CLI 验证下载的包的注册表签名。

可以使用以下 audit 命令验证注册表签名

$ npm audit signatures

audit signatures 命令还将验证下载的包的来源证明。由于来源证明是一项如此新颖的功能,因此随着时间的推移,可能会在证明格式中添加(或更改)安全功能。为了确保始终能够验证证明签名,请检查您是否正在运行最新版本的 npm CLI。请注意,这通常意味着将 npm 更新到高于 Node.js 附带的版本。

如果遵循以下约定,npm CLI 支持任何注册表提供的注册表签名和签名密钥

  1. 签名在包的 packument 中的每个发布版本内的 dist 对象中提供
"dist":{
"..omitted..": "..omitted..",
"signatures": [{
"keyid": "SHA256:{{SHA256_PUBLIC_KEY}}",
"sig": "a312b9c3cb4a1b693e8ebac5ee1ca9cc01f2661c14391917dcb111517f72370809..."
}]
}

请参阅此 示例,了解来自公共 npm 注册表的已签名包。

sig 是使用以下模板生成的:${package.name}@${package.version}:${package.dist.integrity},并且 keyid 必须与下面列出的公共签名密钥之一匹配。

  1. 公共签名密钥在 registry-host.tld/-/npm/v1/keys 中以以下格式提供
{
"keys": [{
"expires": null,
"keyid": "SHA256:{{SHA256_PUBLIC_KEY}}",
"keytype": "ecdsa-sha2-nistp256",
"scheme": "ecdsa-sha2-nistp256",
"key": "{{B64_PUBLIC_KEY}}"
}]
}

密钥响应

  • expires:null 或简化的扩展 ISO 8601 格式YYYY-MM-DDTHH:mm:ss.sssZ
  • keydid:公钥的 sha256 指纹
  • keytype:当前仅支持 ecdsa-sha2-nistp256
  • scheme:当前仅支持 ecdsa-sha2-nistp256
  • key:base64 编码的公钥

请参阅此 来自公共 npm 注册表的示例密钥响应

审计端点

npm 可能使用两个审计端点来获取漏洞信息:批量咨询 端点和 快速审计 端点。

批量咨询端点

从版本 7 开始,npm 使用速度更快的 批量咨询 端点来优化计算审计结果的速度。

npm 将生成一个 JSON 有效负载,其中包含树中每个包的名称和版本列表,并将其发布到默认配置的注册表,路径为 /-/npm/v1/security/advisories/bulk

树中任何其 `package.json` 文件中没有 `version` 字段的包都会被忽略。如果指定了任何 `--omit` 选项(通过 --omit 配置,或其中一个简写形式,例如 --production--only=dev 等),那么将根据需要从提交的有效负载中省略包。

如果注册表响应错误或响应无效,则 npm 将尝试从 Quick Audit 端点加载建议数据。

预期结果将包含一组建议对象,用于与建议范围匹配的每个依赖项。每个建议对象都包含一个 nameurlidseverityvulnerable_versionstitle

然后,npm 使用这些建议对象来计算树中依赖项的漏洞和元漏洞。

快速审计端点

如果 Bulk Advisory 端点返回错误或无效数据,npm 将尝试从 Quick Audit 端点加载建议数据,在大多数情况下,这要慢得多。

将提交在 package-lock.json 中找到的完整包树,以及以下额外的元数据部分

  • npm_version
  • node_version
  • platform
  • arch
  • node_env

将树中的所有包提交到 Quick Audit 端点。在生成报告时,将跳过省略的依赖项类型。

清洗

出于谨慎考虑,npm 5 和 6 版将“清理”提交报告中其名称包含 / 字符的任何包,以避免泄露可能私有包或 git URL 的名称。

但是,在实践中,这会导致审计经常无法正确检测到元漏洞,因为由于缺少依赖项,树将显示为无效,并阻止检测使用 git 依赖项或私有模块的包树中的漏洞。

从 npm 7 版开始,已删除此清理操作。

计算元漏洞和修复

npm 使用 @npmcli/metavuln-calculator 模块将一组安全建议转换为一组“漏洞”对象。 “元漏洞”是由于依赖于易受攻击包的易受攻击版本而易受攻击的依赖项。

例如,如果包 foo 在范围 >=1.0.2 <2.0.0 中存在漏洞,而包 bar 依赖于 foo@^1.1.0,则只能通过安装易受攻击版本的 foo 来安装该版本的 bar。 在这种情况下,bar 是一个“元漏洞”。

计算出给定包的元漏洞后,它们将缓存在 ~/.npm 文件夹中,并且只有在建议范围更改或发布了新版本的包时才会重新评估(在这种情况下,也会检查新版本是否为元漏洞状态)。

如果元漏洞链一直延伸到根项目,并且无法在不更改其依赖项范围的情况下更新,则 npm audit fix 将需要 --force 选项才能应用修复。如果修复不需要更改依赖项范围,则所有易受攻击的包将更新为没有针对其发布建议或元漏洞的版本。

退出代码

如果未发现漏洞,则 npm audit 命令将以 0 退出代码退出。如果未发现漏洞 *或* 修复能够成功修复所有漏洞,则 npm audit fix 命令将以 0 退出代码退出。

如果发现漏洞,退出代码将取决于 audit-level 配置

示例

扫描您的项目以查找漏洞,并自动安装对易受攻击依赖项的任何兼容更新

$ npm audit fix

运行 audit fix 而不修改 node_modules,但仍更新 pkglock

$ npm audit fix --package-lock-only

跳过更新 devDependencies

$ npm audit fix --only=prod

audit fix 安装顶级依赖项的 SemVer 主要更新,而不仅仅是 SemVer 兼容的更新

$ npm audit fix --force

进行一次试运行以了解 audit fix 将执行的操作,*以及* 以 JSON 格式输出安装信息

$ npm audit fix --dry-run --json

扫描您的项目以查找漏洞,只显示详细信息,而不进行任何修复

$ npm audit

以 JSON 格式获取详细的审计报告

$ npm audit --json

如果结果包含中等或更高级别的漏洞,则审计失败

$ npm audit --audit-level=moderate

配置

audit-level

  • 默认:null
  • 类型:null、"info"、"low"、"moderate"、"high"、"critical" 或 "none"

要使 npm audit 以非零退出代码退出,漏洞的最低级别。

dry-run

  • 默认:false
  • 类型:布尔值

表示您不希望 npm 进行任何更改,并且它只应报告它将执行的操作。这可以传递给任何修改本地安装的命令,例如 installupdatededupeuninstall,以及 packpublish

注意:其他网络相关命令(例如 dist-tagsowner 等)不会遵守此设置。

force

  • 默认:false
  • 类型:布尔值

删除针对不幸的副作用、常见错误、不必要的性能下降和恶意输入的各种保护措施。

  • 允许在全局安装中覆盖非 npm 文件。
  • 允许 npm version 命令在未清理的 git 存储库中工作。
  • 允许使用 npm cache clean 删除缓存文件夹。
  • 允许安装具有 engines 声明(要求使用不同版本的 npm)的包。
  • 即使启用了 --engine-strict,也允许安装具有 engines 声明(要求使用不同版本的 node)的包。
  • 允许 npm audit fix 安装超出您声明的依赖项范围的模块(包括 SemVer 主要更改)。
  • 允许取消发布已发布包的所有版本。
  • 允许在根项目中安装冲突的 peerDependencies。
  • npm init 期间隐式设置 --yes
  • 允许覆盖 npm pkg 中的现有值
  • 允许取消发布整个包(而不仅仅是单个版本)。

如果您不确定要做什么,强烈建议您不要使用此选项!

json

  • 默认:false
  • 类型:布尔值

是否输出 JSON 数据,而不是正常输出。

  • npm pkg set 中,它允许使用 JSON.parse() 解析设置值,然后再将其保存到您的 package.json 中。

并非所有 npm 命令都支持。

package-lock-only

  • 默认:false
  • 类型:布尔值

如果设置为 true,则当前操作将只使用 package-lock.json,忽略 node_modules

对于 update,这意味着只有 package-lock.json 会更新,而不是检查 node_modules 并下载依赖项。

对于 list,这意味着输出将基于 package-lock.json 描述的树,而不是 node_modules 的内容。

package-lock

  • 默认:true
  • 类型:布尔值

如果设置为 false,则在安装时忽略 package-lock.json 文件。如果 save 为 true,这也会阻止 *写入* package-lock.json

omit

  • 默认:如果 NODE_ENV 环境变量设置为“production”,则为“dev”,否则为空。
  • 类型:“dev”、“optional”或“peer”(可以设置多次)

要从磁盘上的安装树中省略的依赖项类型。

请注意,这些依赖项 *仍然* 会被解析并添加到 package-lock.jsonnpm-shrinkwrap.json 文件中。它们只是不会物理安装在磁盘上。

如果包类型同时出现在 --include--omit 列表中,则它将被包含。

如果生成的省略列表包含 'dev',则 NODE_ENV 环境变量将为所有生命周期脚本设置为 'production'

include

  • 默认
  • 类型:“prod”、“dev”、“optional”或“peer”(可以设置多次)

允许定义要安装的依赖项类型的选项。

这是 --omit=<type> 的反面。

--include 中指定的依赖项类型不会被省略,无论在命令行中省略/包含的指定顺序如何。

foreground-scripts

  • 默认:false,除非在使用 npm packnpm publish 时,其默认值为 true
  • 类型:布尔值

在前景进程中运行所有构建脚本(即 preinstallinstallpostinstall)脚本,以便安装的包共享标准输入、输出和错误,以及主 npm 进程。

请注意,这通常会使安装运行得更慢,并且会更吵闹,但对调试很有用。

ignore-scripts

  • 默认:false
  • 类型:布尔值

如果为 true,则 npm 不会运行 `package.json` 文件中指定的脚本。

请注意,如果设置了 ignore-scripts,则明确用于运行特定脚本的命令(例如 npm startnpm stopnpm restartnpm testnpm run-script)仍将运行其目标脚本,但它们 *不会* 运行任何预脚本或后脚本。

workspace

  • 默认
  • 类型:字符串(可以设置多次)

启用在当前项目的已配置工作区的上下文中运行命令,同时通过仅运行此配置选项定义的工作区来过滤。

workspace 配置的有效值为以下其中一项

  • 工作区名称
  • 工作区目录的路径
  • 父工作区目录的路径(将导致选择该文件夹中的所有工作区)

npm init 命令中设置时,这可以设置为尚未存在的工作区的文件夹,以便创建该文件夹并将其设置为项目中的全新工作区。

此值不会导出到子进程的环境中。

workspaces

  • 默认:null
  • 类型:null 或布尔值

设置为 true 以在 **所有** 已配置工作区的上下文中运行命令。

明确地将此设置为 false 将导致诸如 install 之类的命令完全忽略工作区。当未明确设置时

  • node_modules 树上操作的命令(安装、更新等)将工作区链接到 node_modules 文件夹中。 - 其他命令(测试、执行、发布等)将在根项目上运行,*除非* 在 workspace 配置中指定了一个或多个工作区。

此值不会导出到子进程的环境中。

include-workspace-root

  • 默认:false
  • 类型:布尔值

在为命令启用工作区时包含工作区根目录。

当为 `false` 时,通过 workspace 配置指定单个工作区,或通过 workspaces 标志指定所有工作区,将导致 npm 仅对指定的工作区进行操作,而不是在根项目上进行操作。

此值不会导出到子进程的环境中。

  • 默认:false
  • 类型:布尔值

当设置为 `file:` 协议依赖项时,将被打包并安装为常规依赖项,而不是创建符号链接。此选项对工作区没有影响。

另请参见