Every CVE Search/ Get API key

CVE-2026-112950

Vitest: Windows backslash traversal bypasses the @vitest/mocker redirect allowlist fix

5.9 MediumFix available

CVE-2026-112950 is a medium vulnerability (CVSS 5.9) in @vitest Mocker, published October 20, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.54%, the 45th percentile. Fixed in @vitest/mocker 4.1.12.

Vitest is a Vite-native testing framework for JavaScript and TypeScript projects. From 4.1.11 until 4.1.12 and 5.0.3, isFileLoadingAllowed and the filesystem read interpret backslashes differently on Windows in packages/mocker/src/node/interceptorPlugin.ts. When a client can reach the Vite dev server on Windows and register a redirect mock containing backslash traversal, POSIX joining preserves a Windows backslash traversal that the later filesystem read interprets as a path separator, so the client can read a file outside server.fs.allow that the Vitest process can access. This issue is fixed in versions 4.1.12 and 5.0.3.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
High
Privileges needed
None
User interaction
None

What an attacker can affect

Confidentiality
High
Integrity
None
Availability
None

Exploit likelihood

0.54%Up 0.2 points since Oct 21, 2026
90%50%10%1%

What each source reports

CVE List Score used 5.9

Vitest: Windows backslash traversal bypasses the @vitest/mocker redirect allowlist fix

Vitest is a Vite-native testing framework for JavaScript and TypeScript projects. From 4.1.11 until 4.1.12 and 5.0.3, isFileLoadingAllowed and the filesystem read interpret backslashes differently on Windows in packages/mocker/src/node/interceptorPlugin.ts. When a client can reach the Vite dev server on Windows and register a redirect mock containing backslash traversal, POSIX joining preserves a Windows backslash traversal that the later filesystem read interprets as a path separator, so the client can read a file outside server.fs.allow that the Vitest process can access. This issue is fixed in versions 4.1.12 and 5.0.3.

Record
CVE-2026-112950
CVSS 3.1
5.9 MediumCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N
Weakness
CWE-22
Updated
2026-11-02
EUVDEUVD-2026-105152 5.9

Vitest is a Vite-native testing framework for JavaScript and TypeScript projects. From 4.1.11 until 4.1.12 and 5.0.3, isFileLoadingAllowed and the filesystem read interpret backslashes differently on Windows in packages/mocker/src/node/interceptorPlugin.ts. When a client can reach the Vite dev server on Windows and register a redirect mock containing backslash traversal, POSIX joining preserves a Windows backslash traversal that the later filesystem read interprets as a path separator, so the client can read a file outside server.fs.allow that the Vitest process can access. This issue is fixed in versions 4.1.12 and 5.0.3.

Record
EUVD-2026-105152
CVSS 3.1
5.9 MediumCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N
Updated
2026-11-02
GitHub AdvisoriesGHSA-xp26-3454-mjgp 5.9

Vitest: Windows backslash traversal bypasses the @vitest/mocker redirect allowlist fix

Summary

The path traversal fix released for GHSA-82fw-gwwq-j7x9 can be bypassed on Windows by using a backslash in the redirect URL pathname.

The fixed code joins an attacker-controlled URL pathname with the Vite root using node:path/posix, then passes that string to Vite's file allowlist check. On Windows, a value such as C:/project/root/..\secret.txt retains ..\ during the POSIX join and begins with the allowed root, so the allowlist accepts it. The later readFile() call uses Windows filesystem semantics, where the backslash is a path separator, and reads the sibling file outside the configured root.

I reproduced the issue with the published @vitest/mocker packages in both fixed release lines:

The current main source at commit 2ce29d5fa758046e5453bd92b8ed6c9da9709bb5 has the same behavior.

Patches

Fixed in @vitest/mocker 5.0.3, released on 2026-09-30 (PR #11377), and backported to 4.1.12. The redirect registration now converts backslashes in the URL pathname to forward slashes before it joins the pathname with the root, so ..\ resolves the same as ../ and the allowlist check rejects it.

Relationship to GHSA-82fw-gwwq-j7x9

This is a bypass of the accepted fix, not a separate unrelated path. It uses the same vitest:interceptor:register redirect registration and the same file-reading sink as the original advisory. A forward-slash traversal is rejected after the fix, while the equivalent Windows backslash traversal is accepted.

The original advisory marks 4.1.11 and 5.0.0-rc.2 as patched. The newly affected ranges introduced by the incomplete fix are therefore:

  • 4.1.11
  • >=5.0.0-rc.2, <5.0.3

Older affected releases remain covered by GHSA-82fw-gwwq-j7x9.

Root cause

packages/mocker/src/node/interceptorPlugin.ts imports join from node:path/posix. Redirect registration currently performs the equivalent of:

const redirect = join(server.config.root, redirectUrl.pathname)
if (!isFileLoadingAllowed(server.config, redirect)) return
event.redirect = redirect

The registered value later reaches:

readFile(mock.redirect, 'utf-8')

Vite's allowlist check expects a normalized absolute filesystem path. On Windows, POSIX joining does not normalize backslashes, but readFile interprets them as separators. The check and the sink therefore interpret the same string differently.

The authenticated browser RPC fallback in packages/browser/src/node/rpc.ts is not affected: it joins the path with pathe, which converts backslashes to forward slashes before the access check. The reproduction below targets the public mocker WebSocket registration path.

Preconditions and impact

A client that can reach a Vite server using the public mockerPlugin or standalone interceptorPlugin WebSocket registration can register a redirect mock. On Windows, the client can then request the registered module and read a file outside server.fs.allow that the Vitest/Vite process account can access. Vitest Browser Mode does not register these WebSocket handlers in the affected versions.

The reproduction uses an unauthenticated Vite HMR WebSocket connection and a normal HTTP GET. It does not call the plugin's internal transform API. The practical network reachability is the same deployment precondition described by the original advisory; default loopback-only development servers are correspondingly less exposed.

Reproduction

Tested on GitHub-hosted Windows Server 2025 with Node.js 22. The test creates only temporary synthetic files: a Vite root directory and a sibling secret.txt containing a canary.

Install dependencies for either affected line:

npm install @vitest/[email protected] [email protected] [email protected]
# or
npm install @vitest/[email protected] [email protected] [email protected]
node poc.mjs

poc.mjs:

import { mkdir, writeFile } from…
Record
GHSA-xp26-3454-mjgp
CVSS 3.1
5.9 MediumCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N
Weakness
CWE-22
Updated
2026-11-02
NVD 5.9

Vitest is a Vite-native testing framework for JavaScript and TypeScript projects. From 4.1.11 until 4.1.12 and 5.0.3, isFileLoadingAllowed and the filesystem read interpret backslashes differently on Windows in packages/mocker/src/node/interceptorPlugin.ts. When a client can reach the Vite dev server on Windows and register a redirect mock containing backslash traversal, POSIX joining preserves a Windows backslash traversal that the later filesystem read interprets as a path separator, so the client can read a file outside server.fs.allow that the Vitest process can access. This issue is fixed in versions 4.1.12 and 5.0.3.

Record
CVE-2026-112950
CVSS 3.1
5.9 MediumCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N
Weakness
CWE-22
Updated
2026-11-02
OSV 5.9

Vitest: Windows backslash traversal bypasses the @vitest/mocker redirect allowlist fix

Vitest is a Vite-native testing framework for JavaScript and TypeScript projects. From 4.1.11 until 4.1.12 and 5.0.3, isFileLoadingAllowed and the filesystem read interpret backslashes differently on Windows in packages/mocker/src/node/interceptorPlugin.ts. When a client can reach the Vite dev server on Windows and register a redirect mock containing backslash traversal, POSIX joining preserves a Windows backslash traversal that the later filesystem read interprets as a path separator, so the client can read a file outside server.fs.allow that the Vitest process can access. This issue is fixed in versions 4.1.12 and 5.0.3.

Record
CVE-2026-112950
CVSS 3.1
5.9 MediumCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N
Weakness
CWE-22
Updated
2026-11-02
OSVGHSA-xp26-3454-mjgp 5.9

Vitest: Windows backslash traversal bypasses the @vitest/mocker redirect allowlist fix

Summary

The path traversal fix released for GHSA-82fw-gwwq-j7x9 can be bypassed on Windows by using a backslash in the redirect URL pathname.

The fixed code joins an attacker-controlled URL pathname with the Vite root using node:path/posix, then passes that string to Vite's file allowlist check. On Windows, a value such as C:/project/root/..\secret.txt retains ..\ during the POSIX join and begins with the allowed root, so the allowlist accepts it. The later readFile() call uses Windows filesystem semantics, where the backslash is a path separator, and reads the sibling file outside the configured root.

I reproduced the issue with the published @vitest/mocker packages in both fixed release lines:

The current main source at commit 2ce29d5fa758046e5453bd92b8ed6c9da9709bb5 has the same behavior.

Patches

Fixed in @vitest/mocker 5.0.3, released on 2026-09-30 (PR #11377), and backported to 4.1.12. The redirect registration now converts backslashes in the URL pathname to forward slashes before it joins the pathname with the root, so ..\ resolves the same as ../ and the allowlist check rejects it.

Relationship to GHSA-82fw-gwwq-j7x9

This is a bypass of the accepted fix, not a separate unrelated path. It uses the same vitest:interceptor:register redirect registration and the same file-reading sink as the original advisory. A forward-slash traversal is rejected after the fix, while the equivalent Windows backslash traversal is accepted.

The original advisory marks 4.1.11 and 5.0.0-rc.2 as patched. The newly affected ranges introduced by the incomplete fix are therefore:

  • 4.1.11
  • >=5.0.0-rc.2, <5.0.3

Older affected releases remain covered by GHSA-82fw-gwwq-j7x9.

Root cause

packages/mocker/src/node/interceptorPlugin.ts imports join from node:path/posix. Redirect registration currently performs the equivalent of:

const redirect = join(server.config.root, redirectUrl.pathname)
if (!isFileLoadingAllowed(server.config, redirect)) return
event.redirect = redirect

The registered value later reaches:

readFile(mock.redirect, 'utf-8')

Vite's allowlist check expects a normalized absolute filesystem path. On Windows, POSIX joining does not normalize backslashes, but readFile interprets them as separators. The check and the sink therefore interpret the same string differently.

The authenticated browser RPC fallback in packages/browser/src/node/rpc.ts is not affected: it joins the path with pathe, which converts backslashes to forward slashes before the access check. The reproduction below targets the public mocker WebSocket registration path.

Preconditions and impact

A client that can reach a Vite server using the public mockerPlugin or standalone interceptorPlugin WebSocket registration can register a redirect mock. On Windows, the client can then request the registered module and read a file outside server.fs.allow that the Vitest/Vite process account can access. Vitest Browser Mode does not register these WebSocket handlers in the affected versions.

The reproduction uses an unauthenticated Vite HMR WebSocket connection and a normal HTTP GET. It does not call the plugin's internal transform API. The practical network reachability is the same deployment precondition described by the original advisory; default loopback-only development servers are correspondingly less exposed.

Reproduction

Tested on GitHub-hosted Windows Server 2025 with Node.js 22. The test creates only temporary synthetic files: a Vite root directory and a sibling secret.txt containing a canary.

Install dependencies for either affected line:

npm install @vitest/[email protected] [email protected] [email protected]
# or
npm install @vitest/[email protected] [email protected] [email protected]
node poc.mjs

poc.mjs:

import { mkdir, writeFile } from…
Record
GHSA-xp26-3454-mjgp
CVSS 3.1
5.9 MediumCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N
Weakness
CWE-22
Updated
2026-11-02
OSVCLSA-2026-1792617972 No score

TuxCare security update for vitest (1 CVE)

TuxCare rebuilt vitest to address 1 CVE. Fixed in 3.2.7-tuxcare.2.

Record
CLSA-2026-1792617972
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
@vitest/mocker
npm
4.1.11 up to 4.1.12
4.1.12
@vitest/mocker
npm
5.0.0-rc.2 up to 5.0.3
5.0.3
vitest
TuxCare:npm
3.2.7-tuxcare.0 up to 3.2.7-tuxcare.2, plus listed versions
3.2.73.2.7-tuxcare.1
3.2.7-tuxcare.2

History

History
WhenChangedSources
2026-11-02createdCVE List, EUVD, GitHub Advisories, NVD, OSV

References

This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open