当前位置: 首页 > news >正文

Vite信息泄露 | CVE-2025-46565 复现研究

0x0 背景介绍

Vite 是一个用于 JavaScript 的前端工具框架。在 6.3.4、6.2.7、6.1.6、5.4.194.5.14 之前的版本中,项目根目录下被文件匹配模式拒绝的文件内容可能会被返回给浏览器。只有明确将Vite 开发服务器暴露给网络的应用程序(使用 --hostserver.host 配置选项)会受到影响。只有位于项目根目录下且被文件匹配模式拒绝的文件可能被绕过。server.fs.deny 可以包含匹配文件的模式(默认情况下,它包括 .env.env.**.{crt,pem} 等模式)。这些模式能够通过使用斜杠和点(/.)的组合来绕过 root 下的文件。该问题已在 6.3.4、6.2.7、6.1.6、5.4.194.5.14 版本中修复。

0x1 环境搭建

1. Ubuntu24环境复现

  • 另存为install.sh并赋予执行权限chmod +x install.sh
#!/bin/bashecho "[+] 开始搭建 Vite CVE-2025-46565 漏洞复现环境"
echo "[+] 目标:使用 vite@6.3.3 复现路径遍历漏洞(/.env/.)"# 步骤 1:创建项目目录
echo -e "\n[+] 步骤 1/7:创建项目目录"
mkdir -p vite-poc && cd vite-poc
echo "[+] 已创建目录:$(pwd)"# 步骤 2:初始化 npm 项目
echo -e "\n[+]  步骤 2/7:初始化 npm"
npm init -y
echo "[+] package.json 已生成"# 步骤 3:安装易受攻击的 Vite 版本
echo -e "\n[+]  步骤 3/7:安装 vite@6.3.3(受影响版本)"
npm install vite@6.3.3
echo "[+]  Vite 6.3.3 安装完成"# 步骤 4:创建 index.html
echo -e "\n[+] 步骤 4/7:创建 index.html"
cat > index.html << 'EOF_HTML'
<!DOCTYPE html>
<html><body><h1>Vite CVE-2025-46565 PoC</h1><p>如果能通过 /%2E.env%2E/ 读取 .env 文件,则存在漏洞。</p></body>
</html>
EOF_HTML
echo "✅ index.html 创建成功"# 步骤 5:创建多个敏感文件(模拟真实项目)
echo -e "\n[+] 步骤 5/7:创建敏感配置文件"# .env
cat > .env << 'EOF_ENV'
SECRET_KEY=ThisIsASecretPassword
DB_PASS=root123
API_TOKEN=abc123xyz
EOF_ENV# .env.local
cat > .env.local << 'EOF_LOCAL'
DATABASE_URL=mysql://devuser:devpass@localhost/devdb
JWT_SECRET=local_jwt_secret_456
EOF_LOCAL# ca.pem
cat > ca.pem << 'EOF_PEM'
-----BEGIN CERTIFICATE-----
MIIDdzCCAl+gAwIBAgIUJfZ1R03qI3Q6OzJd9P/XuXjNvRMwDQYJKoZIhvcNAQELBQAw
EjEQMA4GA1UEAwwHY2EtY2VydDAeFw0yNTAxMDEwMDAwMDBaFw0zNTAxMDEwMDAwMDBa
MBIxEDAOBgNVBAMMB2NhLWNlcnQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
AQC9JZt1...(模拟证书内容)
-----END CERTIFICATE-----
EOF_PEM# .npmrc
echo "[+]//registry.npmjs.org/:_authToken=abcdefg12345" > .npmrcecho "[+] 敏感文件已创建:.env, .env.local, ca.pem, .npmrc"# 步骤 6:创建 vite.config.js
echo -e "\n[+] 步骤 6/7:创建 vite.config.js(启用 --host)"
cat > vite.config.js << 'EOF_CONFIG'
export default {server: {host: '0.0.0.0',port: 5173}
}
EOF_CONFIG
echo "[+] vite.config.js 配置完成(允许外部访问)"# 步骤 7:添加 dev 脚本
echo -e "\n[+] 步骤 7/7:添加启动脚本"
npm pkg set scripts.dev="vite"
echo "[+] 启动脚本已添加:npm run dev"# 结束提示
echo -e "\n🎉 环境搭建完成!"
echo "📌 接下来你可以:"
echo ""
echo "   1️⃣ cd进入项目目录,启动 Vite 服务器:"
echo "      npx vite --host"
echo ""
echo "💡 注意:保持服务器运行,不要关闭当前终端。"

2. 启动成功

项目启动成功

0x2 漏洞复现

手动复现步骤

  • 正常请求文件时,被拒绝的响应
    403拒绝

  • 绕过访问
    访问成功

  • 多姿势绕过访问
    多姿势绕过

  • 示例其它文件
    ca.pem文件

YML检测

https://github.com/Kai-One001/cve-/blob/main/Vite-CVE-2025-46565.yml

YML检测

复现流量特征 (PACP)

0、读取文件

读取env文件

2、多姿势绕过

在这里插入图片描述

0x3 漏洞原理分析

确定入口:静态文件服务

  • Vite 是一个开发服务器,处理静态文件的逻辑在:/packages/vite/src/node/server/middlewares/static.ts

  • 进去后查询发现ensureServingAccess,它是静态资源访问控制的核心入口函数,负责判断请求路径是否允许被服务

  • 并且它调用了 isFileServingAllowed(url, server)来进行权限校验

export function ensureServingAccess(...) {if (isFileServingAllowed(url, server)) {return true}if (isFileReadable(cleanUrl(url))) {// → 返回 403 错误页面} else {next() // → 继续中间件链}return false
}
  • 如果 isFileServingAllowed 返回 false,但文件不可读(不存在),就 next() → 404
  • 如果文件可读,就返回403错误页面

调用 ensureServingAccess 的上下文

  • 在静态中间件中,路径解析完成后立即调用 ensureServingAccess 做安全检查:
#静态文件服务中间件const resolvedPathname = redirectedPathname || pathnamelet fileUrl = path.resolve(dir, removeLeadingSlash(resolvedPathname))if (resolvedPathname.endsWith('/') && fileUrl[fileUrl.length - 1] !== '/') {fileUrl = withTrailingSlash(fileUrl)}//  安全检查:是否允许访问此路径?if (!ensureServingAccess(fileUrl, server, res, next)) {return}
  • 使用 path.resolve() 将 URL 路径转换为本地文件系统绝对路径
  • 调用 ensureServingAccess 进行访问控制
  • 若检查失败则直接中断流程,防止敏感文件泄露
  • 顺着看ensureServingAccess具体实现方法:
export function ensureServingAccess(url: string,server: ViteDevServer,res: ServerResponse,next: Connect.NextFunction,
): boolean {if (isFileServingAllowed(url, server)) {return true  // 允许访问}// ... 否则返回 403
}
  • 所以真正决定是否允许访问的是:isFileServingAllowed

核心权限判断:isFileServingAllowed

export function isFileLoadingAllowed(config: ResolvedConfig,filePath: string,
): boolean {const { fs } = config.serverif (!fs.strict) return trueif (config.fsDenyGlob(filePath)) return falseif (config.safeModulePaths.has(filePath)) return trueif (fs.allow.some((uri) => isUriInFilePath(uri, filePath))) return truereturn false
}
  • 它把 url(如 /.env/.)转换成 filePath
  • 转换函数是:fsPathFromUrl(url)
  • 然后传给 isFileLoadingAllowed做最终判断
  • config.fsDenyGlob(filePath) 使用 picomatch进行模式匹配。

fsDenyGlob 的生成:动态匹配函数

通过 IDE 全局搜索发现,发现一共就俩个地方使用,另一个就是packages/vite/src/node/config.ts
config.ts

     fsDenyGlob: picomatch(// matchBase: true does not work as it's documented// https://github.com/micromatch/picomatch/issues/89// convert patterns without `/` on our side for nowserver.fs.deny.map((pattern) =>pattern.includes('/') ? pattern : `**/${pattern}`,),{matchBase: false,nocase: true,dot: true,},
  • 使用 picomatch 库,对于不含 / 的模式会转换为 **/pattern
  • 所有不包含 / 的模式(如 .env)会被自动前缀为 **/,变成 **/.env

回头看fsPathFromUrl 方法

查询文件发现是通告导入包进来的

import {fsPathFromId,fsPathFromUrl,isFileReadable,isImportRequest,isInternalRequest,isParentDirectory,isSameFileUri,normalizePath,removeLeadingSlash,urlRE,
} from '../../utils'
  • 也就是packages/vite/src/node/utils.ts中,查询fsPathFromUrl函数
export function fsPathFromUrl(url: string): string {return fsPathFromId(cleanUrl(url))
}
export function fsPathFromId(id: string): string {const fsPath = normalizePath(id.startsWith(FS_PREFIX) ? id.slice(FS_PREFIX.length) : id,)return fsPath[0] === '/' || VOLUME_RE.test(fsPath) ? fsPath : `/${fsPath}`
}
  • 路径会被 normalizePath() 处理,使用 path.posix.normalize()
export function normalizePath(id: string): string {return path.posix.normalize(isWindows ? slash(id) : id)
}
  • 使用 path.posix.normalize() 对路径进行标准化
  • 在 Windows 上会先转为正斜杠 /
  • 不会移除末尾的 /./.. 中的点目录

总结:漏洞成因链

用户请求 → /.env/.↓path.resolve() → 解析为本地路径↓fsPathFromUrl() → 转换为文件系统路径↓normalizePath() → 得到 "/.env/."(未清理末尾 .)↓
config.fsDenyGlob("/.env/.") → picomatch('**/.env') 不匹配↓
isFileLoadingAllowed → 返回 true(误判为合法)↓
Vite 尝试读取 "/.env/." → 实际访问 .env 内容或返回 403

0x4 修复建议

修复方案

  1. 升级到安全版本:6.3.4、6.2.7、6.1.6、5.4.19 和 4.5.14版本中已修复
  2. 临时缓解措施:
    部署 Web 应用防火墙(WAF)监控异常请求
    server.fs.allow 配置仅包含必要的目录
    开发服务器不应暴露在公网
    轮换API、数据库密钥

免责声明:本文仅用于安全研究目的,未经授权不得用于非法渗透测试活动。

http://www.dtcms.com/a/542410.html

相关文章:

  • 将火山云TOS存储桶挂载到Linux服务器
  • 网站模板上传什么网站可以做数据调查
  • MongoDB数据库
  • 每天学英语(一)积极向上科技——东方仙盟炼气期
  • 织梦网站上传路径不对揭阳网站设计制作
  • 外贸网站建设 杭州网站建设都包括哪些方面
  • iis网站属性没有asp.net静态页面是什么意思
  • C++ 模板进阶
  • 怎么设置网站栏目百度推广营销
  • 国产MCU芯片在船舶压力传感器中的应用探索与实践
  • 关于网站建设的软文做球球棒棒糖网站源码
  • 网站开发教程pdf网络销售
  • 网站图片上传却不显示不出来亳州网站网站建设
  • 工商网站备案办法深圳 网站托管
  • 【元器件专题】电容核心知识-无极性电容(二)
  • progen2 docker镜像打包命令文档
  • 陇南市城乡建设局网站佛山网站建设 合优
  • 门户网站推广方案台州品牌设计公司
  • 临沧市住房和城乡建设局网站类模板模板下载网站有哪些
  • 网站备案幕布要求广西柳州网站建设
  • 广西住房与城乡建设部网站在线探测网站开发语言
  • 余姚市住房和城乡建设局网站网站优化推广哪家好
  • 稍微写了个屏保(GXDE 一言屏保)
  • 广州h5网站建设公司wordpress 100万数据
  • 【工具】llama factory默认的optimizer
  • (论文速读)HVI:一种用于弱光图像增强的新色彩空间
  • 随笔|富在术数,不在劳身
  • server2008做DNS与网站带论坛的网站模板下载地址
  • OpenObserve轻量化监控:10分钟部署全链路观测平台,资源占用降低70%!
  • 网站用图要怎么做怎么查有做网站的公司