npm包漏洞探究

1. 开始

经常看见一些地方说某些npm包存在漏洞,具体是哪里有漏洞呢,会危害到哪方面呢,是以什么方式造成的呢?

我十分好奇,决定一探究竟,本文用来记录npm包漏洞的内部原因,会持续更新。

2. glob-parent

这个包的作用是在glob表达式中,提取非魔法字符串的部分,比如:

ts 复制代码
var globParent = require('glob-parent');

globParent('path/to/*.js'); // 'path/to'
globParent('/root/path/to/*.js'); // '/root/path/to'
globParent('/*.js'); // '/'
globParent('*.js'); // '.'
globParent('**/*.js'); // '.'
globParent('path/{to,from}'); // 'path'
globParent('path/!(to|from)'); // 'path'

这个包被webpack-dev-server、chokidar、eslint等流行库使用。

该库在<5.1.2前有ReDos(Denial of service)攻击风险,个人理解就是会让执行变慢,攻击者可以使用特殊文件或字符,使服务器不能正常工作。

漏洞前的代码:

ts 复制代码
var enclosure = /[\{\[].*[\/]*.*[\}\]]$/;

修复后的代码:

ts 复制代码
var enclosure = /[\{\[].*[\}\]]$/;

如何检测呢,如果下面的测试用例超时,则说明存在ReDoc风险。

ts 复制代码
it('should not be susceptible to SNYK-JS-GLOBPARENT-1016905', function(done) {
  // This will time out if susceptible.
  gp('{' + '/'.repeat(5000));

  done();
});

根本原因是正则的回溯原理,也就是.*已经包含了[\/]*,没必要再用[\/]*.*了,具体的执行步骤差异不是成倍,而是指数级的。

可以用这个网站查看两个正则解析的性能差异,上面的测试用例,修复前执行时间超过2s,修复后执行只需要0.8ms。

下面是一些思考,其实我们自己写代码时,也有可能写出性能极差的正则,但是并不会被漏洞检测机构收录,可能是因为我们写的库用途不广,并不是基础库,没有被大型项目使用。

参考:

3. xlsx

这个包<0.19.3的版本都有原型污染的漏洞,另外这个库已经不在github和npm上更新了,需要这样更新:

bash 复制代码
npm i https://cdn.sheetjs.com/xlsx-0.19.3/xlsx-0.19.3.tgz

看了下代码,并没有找到相关的漏洞修复提交记录,不知道是不是换了个源,人们就认为它修复了呢?

参考:

4. file-type

这个包也是会引起Dos攻击,原因是读取 MKV 文件的时候处理不当,会造成无限循环。

有问题的版本为>= 17.0.0, < 17.1.3和>= 13.0.0, < 16.5.4,修复的版本为17.1.3和16.5.4。

参考:

5. ejs

ejs是个模版解析工具,被express等库使用。

首先它本身是个javascript运行时工具,开发者需要自己对数据进行校验后再进行下一步处理或输出,不能这样:

js 复制代码
const express = require('express');
const app = express();
const PORT = 3000;
app.set('views', __dirname);
app.set('view engine', 'ejs');

app.get('/', (req, res) => {
    res.render('index', req.query);
});

app.listen(PORT, ()=> {
    console.log(`Server is running on ${PORT}`);
});

有关ejs本身的漏洞是这样的,在query中的参数没被过滤,可以直接运行,造成RCE(远程代码执行remote command/code execute)攻击。

有问题的版本为< 3.1.7,修复的版本为>= 3.1.7。

参考:

6. qs

qs是字符串解析库,使用非常广泛。

关于它的一个漏洞也是原型污染类的,因为它可以用来解析对象,解决办法也很简单,就是过滤__proto__属性即可。

影响版本 修复版本
>= 6.10.0, < 6.10.3 6.10.3
>= 6.9.0, < 6.9.7 6.9.7
>= 6.8.0, < 6.8.3 6.8.3
>= 6.7.0, < 6.7.3 6.7.3
>= 6.6.0, < 6.6.1 6.6.1
>= 6.5.0, < 6.5.3 6.5.3
>= 6.4.0, < 6.4.1 6.4.1
>= 6.3.0, < 6.3.3 6.3.3
< 6.2.4 6.2.4

参考:

相关推荐
LRL_3 天前
跨平台 Node 模块安装指南:如何利用 pnpm/npm 配置`supportedArchitectures` 锁定平台依赖
前端·npm·node.js
guslegend4 天前
脚手架原理与本地调试:从 bin 软链接到 npm link
前端·npm·node.js·脚手架·前端工程化
孟陬6 天前
#教程 dw, dm, dy, d18m 是何意?万物可 Badge | 定制漂亮精致小徽章,打造眼前一亮 README
npm·github
hasty10 天前
不上传新包,也能改变用户拿到的版本:npm dist-tag 的 OIDC 权限治理
前端·npm·node.js
玖石书11 天前
HiSH 通过 apk 安装 Node.js、npm 与 pnpm
npm·node.js·鸿蒙·hish
FACELESS VOID11 天前
wsl下使用npm,错误识别到了windows下的npm
linux·windows·npm
搬砖的小码农_Sky13 天前
AI Agent:Windows上Node.js安装后 npm -v报错
前端·npm·node.js·人机交互
梅孔立15 天前
Codex 完整教程(Node.js安装 + npm安装Codex + DeepSeek配置 + 快捷键 + 设置)
前端·npm·node.js
AlfredZhao22 天前
npm 源切换:一条命令搞定
npm
@tangguo12323 天前
npm 和 yarn 配置说明
前端·javascript·npm·node.js·yarn