目录
GitHub Advisory Database 是什么数据库
什么是 npm audit
-
npm audit
是npm 6 新增的一个命令,可以允许开发人员分析复杂的代码并查明特定的漏洞。 该命令会在项目中更新或者下载新的依赖包之后自动运行,如果你在项目中使用了具有已知安全问题的依赖,就收到官方的警告通知。 -
npm audit
需要包package.json
和package-lock.json
文件。它是通过分析package-lock.json
文件,继而扫描我们的包分析是否包含漏洞的。 -
npm audit
返回的漏洞数据来源于 Github Advisory Database 。
使用 npm audit
npm 源下,执行 npm audit
,如果有已知漏洞,则会展示该漏洞的信息
如上图,可以看到信息包括了 漏洞涉及问题、漏洞危险等级、所在依赖包,依赖包的依赖层级、详细信息 等等信息。
npm audit 衍生命令
# 扫描项目漏洞把不安全的依赖项自动更新到兼容性版本
npm audit fix
# 在不修改 node_modules 的情况下执行 audit fix,仍然会更改 pkglock
npm audit fix --package-lock-only
# 跳过更新 devDependencies
npm audit fix --only=prod
# 强制执行 audit fix 安装最新的依赖项(toplevel)
npm audit fix --force
# 单纯的获取 audit fix 会做的事,并以 json 格式输出。
npm audit fix --dry-run --json
# 获取详情
npm audit
# 以 JSON 格式打印报告
npm audit --json
# 安装单个包关闭安全审查:
npm install example-package-name --no-audit
# 安装所有包关闭安全审查 - 运行
npm set audit false - 手动将 ~/.npmrc 配置文件中的 audit 修改为 false
npm audit 是否可用和什么相关
首先我们已知,npm audit
需要包package.json
和package-lock.json
文件。它是通过分析 package-lock.json
文件,继而扫描我们的包分析是否包含漏洞的。在使用这个命令的时候,可能有些同学会发现自己终端的 npm
命令不包含 npm audit
这条命令,产生这个问题的原因我们来探究一下。
是否和 npm 源有关?
首先,在 npm
官方源下,是可以运行 npm audit
的,如果切换的 cnpm
源下,就无法调用了。
如上图,在 cnpm
源下,不支持 npm audit
。
那么是什么原因导致的呢
关于这个问题,我们可以自己创建一个私有源,看看有没有这个命令。
创建私有源,可以看看这个工具--verdaccio。verdaccio 可以用于搭建一个私有仓库。具体步骤本文就不细说了,有需要的小伙伴可以看官方文档或者查阅其他笔者的文章。
接下来切入正题,假设我本地已经使用 verdaccio 搭建好了一个私有源,然后我们打开它的配置文件 config.yarm 看看
可以看到在配置中有一个中间件字段,用于确定是否使用 audit
,经过测试,当 enabled:false
时,无法调用npm audit
,当enabled:true
时,可以调用npm audit
。
从这里我们可以知道,不同的 npm
仓库可以决定当前终端是否可以使用 npm audit
命令。
是否和 npm 版本有关?
确定使用 npm audit
所需的版本需为 npm@5.10.0
& npm@6
以及以后版本(node
版本中,并没有与 npm@5.10.0
对应的版本,所以推荐使用 npm@6
以后的版本,也就是 Node
版本大于 10.3.0
版本)
看看不同 npm 版本使用 npm audit 的效果
- Npm 5.6.0 Node版本小于 10.3.0
- npm @5.10.0
可以看到信息来源是 nodesecurity.io/advisories 这个地址,这是 node 安全通告数据库
可以看到信息来源是 github.com/advisories 而该仓库的漏洞来源就包括了之前的 node 安全通告数据库, 至于该仓库漏洞的其他来源可以往下看,后续会有解答
可以看到漏洞来源也是 github.com/advisories ,且展示方式发生了改变。
关于漏洞列表
首先,该漏洞列表的全名叫 - GitHub Advisory Database
GitHub Advisory Database 是什么数据库
About the GitHub Advisory database GitHub 为了让开发者能够轻松实现安全开发,推出了一个名为 Advisory Database 的开放安全咨询数据库,它专注于为开发者提供高质量、可操作的漏洞信息。它不仅仅为 npm 提供漏洞信息。它可以支持不同的生态
Composer (registry: packagist.org/)
Erlang (registry: hex.pm/)
Go (registry: pkg.go.dev/)
GitHub Actions (github.com/marketplace…)
Maven (registry: repo.maven.apache.org/maven2)
npm (registry: www.npmjs.com/)
NuGet (registry: www.nuget.org/)
pip (registry: pypi.org/)
pub (registry: pub.dev/packages/re…)
RubyGems (registry: rubygems.org/)
Rust (registry: crates.io/)
可以看到支持这些生态
GitHub Advisory Database 漏洞来源
- 机器学习和人工审查结合检测 GitHub 上公共提交中的漏洞
- 在 GitHub 上报告的安全公告
这些漏洞谁维护的?
github 内部人员, 社群
具体可以看下面readme
这是仓库 readme,可以看到问题的所在点
有两种方法可以为该存储库中提供的信息做出贡献。
从github.com/advisories,上任何单个建议中,单击针对此漏洞的改进建议(如下所示)以打开“改进的安全建议”表单。编辑表单中的信息,然后单击“提交改进”以打开包含您建议的更改的“拉”请求。或者,您可以直接针对该存储库中的文件提交一个拉请求。为此,请遵循投稿指南。
npm audit fix修复策略
直接依赖漏洞
分三种情况进行实践
不锁版本号
- 当前我们直接依赖了一个具有安全漏洞的
lodash@4.17.4
版本:
json
复制代码
"dependencies": { "lodash": "^4.17.4" }
- 运行 npm audit 查看报告
可以看到给出了建议——运行 npm install lodash@4.17.21
- 通过安全漏洞数据库查看修复版本是
4.17.21
由于 ^4.17.4
的依赖范围是 >=4.0.0 < 5.0.0
,已修复的版本 4.17.21
在这个范围内,那么实际上 npm audit fix
执行的逻辑就是 npm update lodash@4.17.
21。
- 运行
npm audit fix
,查看版本更新
可以看到实际上就是升级到了 4.17.21,由此可以知道,npm audit fix 的策略就是升级到已修复版本。
但是由于4.17.21已经是 lodash 的最大版本,因此还得确定到底是该命令到底将依赖包升级到了修复版,还是最新版
- 继续验证确定到底是升级到修复版,还是最新版
后续找到一个 lodash 4.10.0版本漏洞,4.10.11版本被修复的漏洞条目,用来测试升级版本规律,然后本地安装 lodash 4.10.0 版本,运行 npm audit fix ,发现修复后,包版本变为了4.17.21,而不是 4.10.11,由此得知,npm audit fix 的策略就是升级到最新且已修复的版本,而不是被修复的那一版。(即依赖含有漏洞版本号被修复的版本为)
锁版本号
- 再次通过
npm i lodash@4.17.4
安装回含漏洞版本,将当前版本锁住
- 运行 npm audit fix ,查看效果,可以看到锁住之后,还是会升级到修复版本
大版本升级测试
- 通过
npm i lodash@3.10.1
安装 lodash 3.10.1 版本依赖包,然后运行 npm audit 查看
可以看到相比之前多了一条警告,显示这个包可能是一个breaking changes(重大更改), 对比一下之前安装 loadsh 4.12.4 版本的 npm audit 报告
- 接下来运行 npm audit fix 查看报告
可以看到 npm audit fix 对有报警信息的条目此就无能为力了,并且会建议使用 npm audit fix --force
,或者手动升级。
- 为了再验证是否是大版本问题导致报警,可以再使用 4.0.0版本进行尝试,因为 4.0.0就是 3.10.1 的下一个版本,且大版本已经升级到4.0.0
-
运行
npm i lodash@4.0.0
,安装lodash 4.0.0
版本 -
然后运行
npm audit fix
,发现 lodash 成功升级到 4.17.21
综上所述,可以确定,如果涉及到依赖包的大版本升级,npm audit 会出示一条报警信息,且阻止 npm audit fix
进行自动修复,并建议手动升级或运行 npm audit fix --force
间接依赖漏洞
假设我们现在的依赖路径非常深:@commitlint/cli^7.1.2>@commitlint/load^1.0.1>lodash^3.0.0
因为 @commitlint/load
对 lodash
的依赖是^3.0.0(>=3.0.0 <4.0.0)
,4.17.12
不在这个范围,所以我们不能直接通过升级 Lodash
来修复漏洞,这时我们就要向上层依赖进行分析。
假设此时 @commitlint/load
有一个更新版本 @commitlint/load^1.0.2
对 lodash
的依赖是^4.0.0(>=4.0.0 <5.0.0)
,lodash@4.17.12
在这个依赖范围内,那么修复策略为 npm update @commitlint/load@1.0.2 --depth=2
。
npm update 只会检查更新顶层的依赖,更新更深层次的依赖版本需要使用 --depth 指定更新的深度。
按照这个逻辑,如果 @commitlint/load
也没有找到可以升级的包,那么再到上层依赖查找,直到找到可以修复漏洞的那个层级的依赖。
这里也证明了为什么有些深层次依赖包无视大版本升级了,是因为他的上层依赖被升级了。
npm audit fix修复策略总结
- npm audit fix 关于直接依赖的漏洞修复(也就是记录在 package.json中的依赖),如果涉及大版本的升级,则不会直接升级大版本,会在npm audit 报告会展示警告阻止,如果只是涉及到小版本升级,则会修复到当前大版本下最新且已被修复的版本(锁版本的依赖也会被升级)
- npm audit fix 关于间接依赖( 间接依赖的关系在package.lock.json 有显现,npm audit 报告中也有展示)的升级其实也是遵循了以上的原则,关于为什么有些深层次依赖包无视大版本升级了,是因为他的上层依赖被升级了。
参考文档
docs.npmjs.com/cli/v8/comm…
github.com/advisories
docs.github.com/cn/code-sec…
juejin.cn/post/707823…
www.cnblogs.com/GoodMemoryB…
blog.csdn.net/azl39798585…
转载于:https://juejin.cn/post/7164341054265622541