# npm audit

运行安全检查

# 概要

npm audit [fix|signatures]

# 描述

检查命令将项目中配置的依赖项的描述提交到默认注册中心,并要求报告已知漏洞。如果发现任何漏洞,则将计算影响和适当的补救措施。如果 fix 提供了参数,则将对包树应用补救措施。

如果没有发现漏洞,该命令将以 0 退出。

注意

有些漏洞不能自动修复,需要人工干预或检查。还要注意,由于 npm audit fix 在幕后运行了 npm install 命令,应用于安装程序的所有配置也将应用于 npm install -- 所以类似 npm audit fix --package-lock-only 将按预期工作。

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

# 检查签名

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

可以使用以下 audit 命令验证注册中心签名:

npm audit signatures

npm CLI 支持注册中心签名和签名键值,只要遵循以下约定:

  1. 签名在每个发布版本的包的 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: 目前 npm CLI 只支持 ecdsa-sha2-nistp256
  • scheme: 目前 npm CLI 只支持 ecdsa-sha2-nistp256
  • key: base64 编码的公钥

# 检查端点

npm 可以使用两个审计端点来获取漏洞信息,Bulk Advisory 端点和 Quick Audit 端点

# Bulk Advisory 端点

在版本 7 中,npm 使用更快的 Bulk Advisory 端点优化检查结果的计算速度。

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

如果树中的任何包中没有 version 字段 package.json 文件将被忽略。如果指定了 --omit 选项(要么通过 --omit 配置,要么使用简写 --production, --only=dev,以此类推),将从提交的有效负载中适当地省略包。

如果注册中心响应错误或响应无效,npm 将尝试 Quick Audit 端点。

预期结果将为每个与建议范围匹配的依赖项包含一组建议对象。每个 Advisory 对象包含 name、url、id、severity、vulnerable_versions、title 这些参数。

然后 npm 使用这些 Advisory 对象来计算树中依赖关系的漏洞和元漏洞。

# Quick Audit 端点

如果 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,则bar 只能通过安装易受攻击的 foo. 在这种情况下,bar 是一个“元漏洞”。

一旦计算了给定包的元漏洞,它们就会被缓存在 ~/.npm 文件夹中,并且只有在建议范围发生变化或发布包的新版本时才会重新评估(在这种情况下,还会检查新版本的元漏洞状态))。

如果元漏洞链一直延伸到根项目,并且在不更改其依赖范围的情况下无法更新,则 npm audit fix 需要 --force 选择应用补救措施。如果补救措施不需要更改依赖范围,那么所有易受攻击的软件包都将更新到没有针对它发布建议或元漏洞的版本。

# 退出代码

如果执行 npm audit 命令没有发现漏洞,命令将以 0 进行代码退出。如果执行 npm audit fix 命令没有发现漏洞,或者补救能够成功修复所有漏洞,则命令将以 0 进行代码退出。

如果发现漏洞,退出代码将依赖于配置的 audit-level

# 例子

扫描您的项目中的漏洞,并自动为有漏洞的依赖项安装任何兼容更新:

npm audit fix

在不修改节点模块的情况下运行 audit fix,但仍然更新 pkglock:

npm audit fix --package-lock-only

跳过 devDependencies 更新:

npm audit fix --only=prod

使用 audit fix 安装 SemVer-major 更新到顶级依赖项,而不仅仅是只引入 SemVer-compatible :

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

  • Default: null
  • Type: null, "info", "low", "moderate", "high", "critical", or "none"

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

# dry-run

  • Default: false
  • Type: Boolean

表示您不希望 npm 进行任何更改,并且只报告它应该做的事情。这可以传递到任何修改本地安装的命令中,例如:install, update, dedupe, uninstall 以及 pack 和 publish。

注意

其他相关命令不支持此功能,例如 dist-tags, owner 等。

# force

  • Default: false
  • Type: Boolean

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

  • 允许在全局安装中清除 non-npm 文件。
  • 允许 npm version 命令在不干净的 git 存储库上工作。
  • 允许删除缓存文件夹 npm cache clean
  • 允许安装 engines 声明需要不同版本的 npm 的包。
  • 允许安装 engines 声明需要不同版本的软件包 node,即使 --engine-strict 已启用。
  • 允许 npm audit fix 安装指定依赖范围之外的模块(包括 SemVer-major 的更改)。
  • 允许取消发布已发布包的所有版本。
  • 允许在根项目中安装冲突的 peerDependencies。
  • npm init 中隐式设置 --yes
  • 允许删除 npm pkg 中的现有值。
  • 允许取消发布整个包(不仅仅是单个版本)。

如果您对自己想要做什么没有明确的想法,强烈建议您不要使用此选项!

# json

  • Default: false
  • Type: Boolean

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

  • npm pkg set 支持使用 JSON.parse() 解析集合值,然后保存到你的 package.json

并非所有 npm 命令都支持。

# package-lock-only

  • Default: false
  • Type: Boolean

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

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

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

# omit

  • Default: 'dev' | ''
  • Type: "dev", "optional", or "peer" (可以设置多次)

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

注意

这些依赖项仍然被解析并添加到 package-lock.jsonnpm-shrinkwrap.json 文件中。

如果包类型同时出现在 --include--omit 列表中,那么它将被包括在内。

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

# foreground-scripts

  • Default: false
  • Type: Boolean

在前台进程中运行已安装包的所有构建脚本(ie, preinstall, install, postinstall) ,将与主 npm 进程共享标准输入、输出和错误。

注意

这通常会使安装运行速度变慢,并且噪音更大,但对调试很有用。

# ignore-scripts

  • Default: false
  • Type: Boolean

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

注意

如果设置了 ignore-scripts,那些显式地想要运行特定脚本的命令,比如 npm startnpm stopnpm restartnpm testnpm run-script 仍然会运行它们想要运行的脚本,但是它们不会运行任何前脚本或后脚本。

# workspace

  • Default:
  • Type: String (可以设置多次)

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

workspace 配置的有效值如下:

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

npm init 命令设置时,可以将其设置为尚不存在的工作空间的文件夹,以创建文件夹并将其设置为项目中的全新工作空间。

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

# workspaces

  • Default: null
  • Type: null or Boolean

设置为 true 将在所有配置的工作区中运行该命令。

显式地将此设置为 false 将导致如下命令 install 完全忽略工作空间。当没有显式设置时:

  • node_modules 树上操作的命令 (install, update, etc.) 时,将把工作区链接到 node_modules 文件夹中。做其他事情的命令 (test, exec, publish, etc.) 将在根项目上操作,除非在 workspace 配置中指定了一个或多个工作空间。

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

# include-workspace-root

  • Default: false
  • Type: Boolean

当为某个命令启用工作区时,请包含工作区根目录。

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

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

  • Default: false
  • Type: Boolean

当设置文件: 存在于项目根目录之外的协议依赖项将被打包并安装为常规依赖项,而不是创建符号链接。此选项对工作区没有影响。

Last Updated: 4/25/2023, 9:49:29 AM