标签 PDF生成库 下的文章


一、漏洞概述

2026年1月3日,JavaScript PDF生成库 jsPDF 被披露存在一个严重的路径遍历漏洞(CVE-2025-68428)

该漏洞允许在Node.js环境下读取任意文件,并将敏感内容嵌入生成的PDF文档中,导致数据泄露

漏洞基本信息

项目
详情
CVE编号
CVE-2025-68428
GHSA编号
GHSA-f8cm-6447-x5h2
受影响版本
jsPDF < 4.0.0
修复版本
jsPDF >= 4.0.0
漏洞类型
路径遍历/本地文件包含 (LFI)
CVSS v4.0评分
9.2 (严重)
披露时间
2026年1月3日


二、核心问题

漏洞的核心在于 jsPDF 的Node.js构建版中,多个方法未对传入路径进行严格校验:

受影响的方法:

loadFile() - 底层文件加载函数

addImage() - 添加图片到PDF

html() - 将HTML转换为PDF

addFont() - 添加自定义字体

这些方法内部都会调用 loadFile(),而该函数直接使用用户提供的路径读取文件,没有任何路径遍历防护!

三、漏洞原理分析

3.1 漏洞代码分析

我们本地下载3.0.4这个特定版本的jsPDF

mkdir cve-2025-68428
cd cve-2025-68428
npm init -y
npm install jspdf@3.0.4

漏洞点主要在 node_modulesjspdfdistjspdf.node.js中,代码审计

在15918行发现漏洞函数nodeReadFile

图片.png



漏洞点在15922行和15928行,

1.直接引用了原生的fs模块,看似无害,实际上jsPDF本是为浏览器设计的,在浏览器环境下,调用readFileSync时,浏览器会自动的应用沙箱以及同源策略,不允许也不可能读到本地文件。但是!,当jsPDF 被移植到 Node.js 时,它引入 fs 模块就会存在极大的隐患,url已经从受限的网络地址变成了无限制的磁盘路径,配合后面的读取,直接导致LFI

2.第二个漏洞点,url不仅完全可控,而且没有任何对url的过滤,基本的'../'和绝对路径过滤都没有,导致目录穿越

知道了漏洞的产生,我们看看开发者后面是怎么修复这个漏洞的

3.2怎么修的呢

下载jsPDF4.0.0的源码,审计

在15950行找到修改过的nodeReadFile函数

图片.png

源码如下:

这里有这么一个判断,我们来看看:

翻译翻译,先看这段英文:

你试图从本地文件系统读取文件,但当前既没有用 Node 的安全启动参数,也没有设置 jsPDF 的 allowFsRead。请二选一来启用该功能

开发者并没有完全禁止本地文件的读取,而是加了两个开关,两个条件同时不成立则终止执行,throw出错误

process.permission

接入 Node.js 原生安全权限,如果启动时没带 --allow-fs-readprocess.permission.has('fs.read') 就会返回 false

allowFsRead

库级别开关,如果你在代码里没有显式地设置 doc.allowFsRead = true;,库依然会拒绝执行读取操作,在代码中,allowFsRead是undefined,如果开关是 false,执行流被强行改变

图片.png



然后就是目录穿越漏洞的修复:

path.resolve(url) 先把相对路径转为绝对路径。

fs.realpathSync(...) 会解析所有的符号链接并去掉所有的 .././



最后是基于白名单的边界检查(关键!)

这是修复目录穿越最核心的部分,它会检查“规范化后的真实路径”是否在允许的范围(支持自定义)内:



妙啊,实在是妙啊,要说后面的过滤都还算常规,这个process.permission直接降维打击。

直接接入Node.js原生安全权限,只要Node.js框架安全,LFI就可以被完全杜绝(配置时不要加上--allow-fs-read),直接把防御做到了环境层

你就看看process.permission有多牛吧:

沙箱化能力:类似于浏览器的沙箱。即使你的 JS 代码里有漏洞,只要你在启动 Node 时没有给 /etc/ 的读权限,底层的 C++ 引擎就会直接拒绝操作,这和 JS 逻辑好坏无关

不可逆性:一旦 Node 进程启动并设定了权限,JS 代码无法在运行期间通过某种手段偷偷给自己“提权“

不得不承认,真的学到了,大佬们太强了



修复对比:

维度
修复前
修复后
路径处理
直接使用原始字符串
path.resolve + realpathSync
信任机制
盲目信任用户输入
基于白名单的 startsWith 校验
底层保护
无限制读取
接入 process.permission 权限模型
报错信息
泄露系统真实路径错误
统一返回 "Permission Denied"


四、漏洞复现

1.环境配置要求:

Node.js 环境

npm 包管理器

jspdf@3.0.4



2.测试目录创建:

3.利用脚本

3.1(loadFile触发):(p.js)

搭建完后的目录结构:

图片.png



调用脚本:

图片.png



成功读取win.ini,liunx同理可读/etc/passwd验证

3.2.readFileSync触发(exploit.js):

图片.png



利用成功

图片.png



图片.png



五、利用场景分析

在线PDF生成服务

文档转换服务

这些情形都可以通过目录穿越读取任意文件,结合XXE,日志注入等组合拳实现LFI到RCE,后果极其严重!