CVE-2026-84373
MediumCVSS 5.9Exploitation Probability (EPSS)
Low risk31th percentile - higher than 31% of all known CVEs
Summary
Vitest is a testing framework powered by Vite. From 2.1.0 until 4.1.11 and 5.0.0-rc.2, the public mockerPlugin and standalone interceptorPlugin exports in packages/mocker/src/node/interceptorPlugin.ts register the vitest:interceptor:register handler on Vite's unauthenticated HMR WebSocket without validating redirect targets against the file-serving allowlist. The implementation processes event.redirect without enforcing server.fs.allow and server.fs.deny through isFileLoadingAllowed. A remote client that can reach an exposed development server can submit an opaque URL scheme preserving .. segments, causing join(server.config.root, redirectUrl.pathname) to resolve outside the project root. The plugin's load hook then returns readFile(mock.redirect, 'utf-8') as module source, disclosing local files readable by the dev-server process. Vitest browser mode uses a token-authenticated RPC and is not remotely unauthenticated by default, although the same boundary check was missing on that path. This issue is fixed in versions 4.1.11 and 5.0.0-rc.2.
Risk Assessment
A remote attacker can read local files from the development server, potentially leading to disclosure of source code, configuration data, or other sensitive information. This can compromise project confidentiality.
Recommendation
Update Vitest to version 4.1.11 or 5.0.0-rc.2 (or later). Do not expose the development server to public access.
Other vulnerabilities in Vitest
See all- CVE-2026-73653Critical
Vitest Browser Mode before versions 3.2.7, 4.1.10, and 5.0.0-beta.6 does not enforce the allowWrite permission gate or confine paths to the project root for commands such as upload, takeScreenshot, screenshotMatcher, stopChunkTrace, deleteTracing, and annotateTraces. A client that can reach the Browser Mode API can read arbitrary local files, create or overwrite image and trace files, or delete files accessible to the Vitest process even when allowWrite is false. This issue is fixed in versions 3.2.7, 4.1.10, and 5.0.0-beta.6.
- CVE-2026-53633Critical
A vulnerability in Vitest Browser Mode allows a remote attacker to bypass access controls and execute arbitrary Node.js code. The cdp() API forwards Chrome DevTools Protocol methods without checking allowWrite or allowExec permissions, enabling manipulation of the vite.config.ts file.
- CVE-2026-47429Critical
A vulnerability in the Vitest testing framework on Windows allows reading files outside the project via path traversal in /__vitest_attachment__ and arbitrary code execution through saveTestFile and rerun API functions. Fixed in versions 3.2.5 and 4.1.0.
- CVE-2026-47428Critical
A vulnerability in Vitest Browser Mode allows JavaScript injection via the otelCarrier query parameter in the /__vitest_test__/ path. An attacker can use a crafted URL to execute arbitrary code in the Vitest server origin and recover the VITEST_API_TOKEN for authenticated API calls.
Original NVD description (English source)
Vitest is a testing framework powered by Vite. From 2.1.0 until 4.1.11 and 5.0.0-rc.2, the public mockerPlugin and standalone interceptorPlugin exports in packages/mocker/src/node/interceptorPlugin.ts register the vitest:interceptor:register handler on Vite's unauthenticated HMR WebSocket without validating redirect targets against the file-serving allowlist. The implementation processes event.redirect without enforcing server.fs.allow and server.fs.deny through isFileLoadingAllowed. A remote client that can reach an exposed development server can submit an opaque URL scheme preserving .. segments, causing join(server.config.root, redirectUrl.pathname) to resolve outside the project root. The plugin's load hook then returns readFile(mock.redirect, 'utf-8') as module source, disclosing local files readable by the dev-server process. Vitest browser mode uses a token-authenticated RPC and is not remotely unauthenticated by default, although the same boundary check was missing on that path. This issue is fixed in versions 4.1.11 and 5.0.0-rc.2.

