【问题标题】:Can NPM show me the age of packages before installing them?NPM 可以在安装包之前显示包的年龄吗?
【发布时间】:2022-01-05 18:35:19
【问题描述】:

鉴于现有 npm 包中最近存在恶意软件,我希望有一种机制可以让我在安装新包或更新现有包之前进行一些基本检查。我的主要问题是我直接安装的软件包和间接安装的软件包。

一般来说,我想在安装之前获取 npm 将安装的包版本列表。更具体地说,我想要将要安装的软件包的年龄,因此如果其中任何一个不到一天,我可以生成警告。

如果我可以直接用 npm 做到这一点,那就太好了,但恐怕我需要围绕它编写一些脚本。

具体用例:

如果我在 2021 年 10 月 22 日执行npm install react-native-gesture-handler,它将执行恶意版本的 ua-parser 的安装后挂钩,我的计算机将受到威胁,这是我想避免的。

当我输入 npm install react-native-gesture-handler --dry-run 时,它只告诉我它会安装哪个版本的 react-native-gesture-handler,但它不会告诉我它将安装在那个版本上发布的 ua-parser天。

补充说明:

  • 我知道npm i --dry-run 存在,但它只显示直接包。
  • 我知道 npm list 存在,但它只在安装后显示包(因此在 install-hooks 已经造成伤害之后)
  • 两者都只显示包版本而不是它们的年龄
  • 我不知道如何在安装之前获得安装挂钩随附的软件包列表
  • 欢迎提供处理恶意 npm 包的替代方法。
  • 到目前为止,我最好的解决方案是执行“--ignore-scripts”,但这会带来一系列问题

【问题讨论】:

  • 我能想到的最简单的解决方案是在 docker-container 中执行“npm i && npm list”,然后直接查询 npm 的 api 以获取每个包版本的年龄。我希望有一个更简单的想法。
  • npm i --dry-run 的问题相同。它只显示包本身的数据,而不是任何依赖项。
  • 好吧,我想您可以以某种方式将依赖项解析为单个包 json 文件,然后使用脚本对其进行检查。不知道是否有内置命令
  • npm 客户端是开源的。您可以随时打开拉取请求:github.com/npm/cli

标签: node.js security npm npm-install


【解决方案1】:

要找出恶意程序包,您需要一个脚本来检查您的程序包是否存在针对national vulnerabilities database的漏洞

国家漏洞数据库包括安全清单参考、安全相关软件缺陷、错误配置、产品名称和影响指标的数据库。

大多数软件公司都使用应用程序安全工具,例如 VeracodeSnykCheckmarx,这些工具通常在部署到 CICD 之前的阶段执行此操作管道。

如果您希望在本地实现此目标,可以尝试

npm audit

但这会根据默认注册表(nexus 或 artifactory 或 npm 注册表) 并为您提供已知漏洞列表以及可用补丁的版本详细信息。

npm view 会为您提供以下有关软件包的详细信息,即使它未安装

安装前的版本检查需要一个脚本来在预安装时执行必要的操作,我建议 有一个专门的安全检查项目(可重复用于所有项目),以及linkpublish 然后在您的项目脚本中配置它,例如 下面,

安全项目:

这将有脚本检查漏洞,利用npm viewnpm version 并审核模块然后返回结果。

主要项目:

在这里设置package.json中的脚本以使用上述发布的项目并在安装前检查漏洞。

npx security-project vulnerabilities


scripts: {
  vulnerability: npx security-project vulnerabilities
  preinstall: npx security-project vulnerabilities

  or

  preinstall: "sh ./checkVulnerabilities.sh" // this script can take package name through command line flags like --package axios
}

Snyk 获取您的package.json 并将扫描所有模块以查找安全漏洞。您还可以搜索特定模块并检查版本的健康评分。

https://snyk.io/advisor/check/npm

或者,您也可以在 IDE 中使用 Snyk extension

我们有RetireJS chrome extension 用于扫描应用程序中存在漏洞的易受攻击的 JS 模块版本。

好的参考:-6-tools-you-can-use-to-check-for-vulnerabilities-in-node-js

以上是我能想到的想法,希望对你有所帮助。

【讨论】:

  • 我的问题是针对已推送恶意版本但尚未标记为恶意版本的时间范围。在那短暂的时间里,我完全无助,所以我正在寻找缓解那里的东西。您的回答将有助于缩短该时间,但不会消除它。我也相信,当一个版本是故意恶意的,它会在它被报告给 snyk 等之后很快从 NPM 中提取出来。
  • @wotanii 恶意版本被 NVD 标记和记录。开发人员会推送一个解决该漏洞的补丁,但不会被拉取。您所指的“那短暂的时间”,您如何知道尚未标记的版本是恶意的? npm view 是安装前查看包详细信息的唯一方法。
  • “您如何知道尚未标记为恶意的版本?”正是这个!!我不知道。这就是为什么我想将太新的版本视为“潜在危险”并且只安装足够老的版本,安全审计员可以做他们的事情。话虽这么说:您的答案是完美的规范答案,即使我也不是我一直希望的。
【解决方案2】:

首先以安全的方式安装包,然后使用npm listnpm view 获取安装包的年龄。

选项 1:使用 --ignore-scripts 安装

npm i --ignore-scripts
npm list --depth=100 | awk '{ print $NF }'| tail -n +2 | grep -v "deduped" |  xargs -I {}  bash -c "npm view {} time.modified _id|tr '\n' ' ' && echo "|sort

选项 2:在 docker 中安装

docker run -v $PWD/package.json:/a/package.json -v $PWD/package-lock.json:/a/package-lock.json --rm -it node:lts-buster bash

cd a && npm i
npm list --depth=100 | awk '{ print $NF }'| tail -n +2 | grep -v "deduped" |  xargs -I {}  bash -c "npm view {} time.modified _id|tr '\n' ' ' && echo "|sort

脚本说明,打印日期:

  • npm list --depth=100 获取已安装包列表
  • | awk '{ print $NF }'从每一行提取包的id
  • | tail -n +2 删除第一行,表示当前文件夹
  • | grep -v "deduped" 删除引用欺骗的行
  • | xargs -I {} bash -c 为每一行打开子shell
  • npm view {} time.modified _id 获取时间和包裹ID
  • |tr '\n' ' ' && echo 去掉time和id之间的换行符,在末尾加上换行符
  • |sort 按字母顺序排列行

注意:由于npm view 一次通过网络获取 1 个包,因此每个已安装包的脚本大约需要 1 秒,对于中型项目来说,这将加起来需要几分钟。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-16
    • 2015-07-09
    • 2013-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多