Vite开发服务器任意文件读取漏洞分析复现(CVE-2025-31486)
字数 1516 2025-08-29 22:41:01

Vite开发服务器任意文件读取漏洞分析(CVE-2025-31486) 教学文档

漏洞概述

CVE-2025-31486是Vite开发服务器中的一个任意文件读取漏洞,攻击者可以通过构造特殊请求绕过ensureServingAccess权限校验机制,从而读取服务器上的任意文件。

漏洞背景

此漏洞与之前修复的CVE-2024-45811有关,该修复引入了ensureServingAccess对传入URL进行校验。然而,本漏洞通过特定方式绕过了这一校验机制。

漏洞影响版本

影响Vite 6.2.5之前的版本(具体影响范围需进一步确认)

漏洞原理分析

关键校验流程

漏洞核心在于绕过ensureServingAccess校验,该函数主要逻辑如下:

  1. 首先调用fsPathFromUrl处理URL:

    • 使用cleanUrl移除URL中第一个?#开始到结尾的部分
    • 然后通过fsPathFromId将模块ID转换为文件系统路径
    • normalizePath函数会标准化路径格式(处理反斜杠、多余斜杠和相对路径)
  2. 接着调用isFileLoadingAllowed检查文件路径是否允许加载:

    • 如果fs.strict为false(非严格模式),直接允许加载所有文件
    • 检查文件路径是否命中黑名单(fsDenyGlob
    • 检查是否在明确允许的路径集合中(safeModulePaths
    • 检查是否匹配允许的路径规则(fs.allow数组)

绕过机制

攻击者通过构造特殊URL绕过校验的关键点:

  1. 原始URL格式示例:

    /@fs/usr/src/node_modules/vite/etc/passwd?import&?raw
    
  2. 校验时处理流程:

    • cleanUrl处理后变为:/@fs/usr/src/node_modules/vite/
    • 该路径通过isFileLoadingAllowed检查(因为项目根目录默认在fs.allow中)
    • 但后续处理逻辑仍使用原始URL,导致绕过
  3. fs.allow默认配置:

    • 默认值为[searchForWorkspaceRoot(root)]
    • 自动搜索工作区根目录(包含pnpm-workspace.yamllerna.json的目录)
    • 因此攻击URL必须包含网站路径才能通过校验

最终利用流程

通过校验后,请求进入以下处理流程:

  1. 通过isImportRequest检查
  2. 去除import参数变为:/@fs/usr/src/node_modules/vite/etc/passwd??raw
  3. 进入transformRequestdoTransform
  4. 通过rawRE.test检查(无目录穿越防御)
  5. 最终导致任意文件读取

漏洞复现

POC示例

http://[target]:5173/@fs/usr/src/node_modules/vite/etc/passwd?import&?raw

复现步骤

  1. 启动存在漏洞版本的Vite开发服务器
  2. 构造上述POC URL访问
  3. 服务器将返回/etc/passwd文件内容

修复方案

Vite 6.2.5版本修复了此漏洞,建议升级到最新版本。

防御建议

  1. 及时升级Vite到安全版本
  2. 在生产环境禁用开发服务器功能
  3. 严格限制fs.allow配置,避免使用默认值
  4. 对用户输入进行更严格的路径规范化处理

技术要点总结

  1. ensureServingAccess校验被绕过是漏洞核心
  2. cleanUrl与后续处理逻辑不一致导致绕过
  3. fs.allow默认配置使攻击成为可能
  4. 原始URL中的特殊构造(?import&?raw)是关键
  5. 缺乏对最终文件路径的目录穿越检查

参考链接

Vite开发服务器任意文件读取漏洞分析(CVE-2025-31486) 教学文档 漏洞概述 CVE-2025-31486是Vite开发服务器中的一个任意文件读取漏洞,攻击者可以通过构造特殊请求绕过 ensureServingAccess 权限校验机制,从而读取服务器上的任意文件。 漏洞背景 此漏洞与之前修复的CVE-2024-45811有关,该修复引入了 ensureServingAccess 对传入URL进行校验。然而,本漏洞通过特定方式绕过了这一校验机制。 漏洞影响版本 影响Vite 6.2.5之前的版本(具体影响范围需进一步确认) 漏洞原理分析 关键校验流程 漏洞核心在于绕过 ensureServingAccess 校验,该函数主要逻辑如下: 首先调用 fsPathFromUrl 处理URL: 使用 cleanUrl 移除URL中第一个 ? 或 # 开始到结尾的部分 然后通过 fsPathFromId 将模块ID转换为文件系统路径 normalizePath 函数会标准化路径格式(处理反斜杠、多余斜杠和相对路径) 接着调用 isFileLoadingAllowed 检查文件路径是否允许加载: 如果 fs.strict 为false(非严格模式),直接允许加载所有文件 检查文件路径是否命中黑名单( fsDenyGlob ) 检查是否在明确允许的路径集合中( safeModulePaths ) 检查是否匹配允许的路径规则( fs.allow 数组) 绕过机制 攻击者通过构造特殊URL绕过校验的关键点: 原始URL格式示例: 校验时处理流程: cleanUrl 处理后变为: /@fs/usr/src/node_modules/vite/ 该路径通过 isFileLoadingAllowed 检查(因为项目根目录默认在 fs.allow 中) 但后续处理逻辑仍使用原始URL,导致绕过 fs.allow 默认配置: 默认值为 [searchForWorkspaceRoot(root)] 自动搜索工作区根目录(包含 pnpm-workspace.yaml 或 lerna.json 的目录) 因此攻击URL必须包含网站路径才能通过校验 最终利用流程 通过校验后,请求进入以下处理流程: 通过 isImportRequest 检查 去除 import 参数变为: /@fs/usr/src/node_modules/vite/etc/passwd??raw 进入 transformRequest 和 doTransform 通过 rawRE.test 检查(无目录穿越防御) 最终导致任意文件读取 漏洞复现 POC示例 复现步骤 启动存在漏洞版本的Vite开发服务器 构造上述POC URL访问 服务器将返回 /etc/passwd 文件内容 修复方案 Vite 6.2.5版本修复了此漏洞,建议升级到最新版本。 防御建议 及时升级Vite到安全版本 在生产环境禁用开发服务器功能 严格限制 fs.allow 配置,避免使用默认值 对用户输入进行更严格的路径规范化处理 技术要点总结 ensureServingAccess 校验被绕过是漏洞核心 cleanUrl 与后续处理逻辑不一致导致绕过 fs.allow 默认配置使攻击成为可能 原始URL中的特殊构造( ?import&?raw )是关键 缺乏对最终文件路径的目录穿越检查 参考链接 原始分析文章: Vite开发服务器任意文件读取漏洞分析复现(CVE-2025-31486) 相关CVE:CVE-2024-45811, CVE-2025-31125