CVE-2025-62522
Description
Vite is a frontend tooling framework for JavaScript. In versions from 2.9.18 to before 3.0.0, 3.2.9 to before 4.0.0, 4.5.3 to before 5.0.0, 5.2.6 to before 5.4.21, 6.0.0 to before 6.4.1, 7.0.0 to before 7.0.8, and 7.1.0 to before 7.1.11, files denied by server.fs.deny were sent if the URL ended with \ when the dev server is running on Windows. Only apps explicitly exposing the Vite dev server to the network and running the dev server on Windows were affected. This issue has been patched in versions 5.4.21, 6.4.1, 7.0.8, and 7.1.11.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
vitenpm | >= 7.1.0, < 7.1.11 | 7.1.11 |
vitenpm | >= 7.0.0, < 7.0.8 | 7.0.8 |
vitenpm | >= 6.0.0, < 6.4.1 | 6.4.1 |
vitenpm | >= 2.9.18, < 5.4.21 | 5.4.21 |
vitenpm | >= 3.2.9, < 5.4.21 | 5.4.21 |
vitenpm | >= 4.5.3, < 5.4.21 | 5.4.21 |
vitenpm | >= 5.2.6, < 5.4.21 | 5.4.21 |
Affected products
1Patches
1f479cc57c425fix(dev): trim trailing slash before `server.fs.deny` check (#20968)
2 files changed · +31 −2
packages/vite/src/node/server/middlewares/static.ts+6 −1 modified@@ -297,7 +297,12 @@ export function isFileLoadingAllowed( if (!fs.strict) return true - if (config.fsDenyGlob(filePath)) return false + // NOTE: `fs.readFile('/foo.png/')` tries to load `'/foo.png'` + // so we should check the path without trailing slash + const filePathWithoutTrailingSlash = filePath.endsWith('/') + ? filePath.slice(0, -1) + : filePath + if (config.fsDenyGlob(filePathWithoutTrailingSlash)) return false if (config.safeModulePaths.has(filePath)) return true
playground/fs-serve/__tests__/fs-serve.spec.ts+25 −1 modified@@ -13,7 +13,14 @@ import { import type { Page } from 'playwright-chromium' import WebSocket from 'ws' import testJSON from '../safe.json' -import { browser, isServe, page, viteServer, viteTestUrl } from '~utils' +import { + browser, + isServe, + isWindows, + page, + viteServer, + viteTestUrl, +} from '~utils' const __dirname = path.dirname(fileURLToPath(import.meta.url)) @@ -538,6 +545,23 @@ describe.runIf(isServe)('invalid request', () => { expect(response).toContain('HTTP/1.1 403 Forbidden') }) + test('should deny request to denied file when a request ends with \\', async () => { + const response = await sendRawRequest(viteTestUrl, '/src/.env\\') + expect(response).toContain( + isWindows ? 'HTTP/1.1 403 Forbidden' : 'HTTP/1.1 404 Not Found', + ) + }) + + test('should deny request to denied file when a request ends with \\ with /@fs/', async () => { + const response = await sendRawRequest( + viteTestUrl, + path.posix.join('/@fs/', root, 'root/src/.env') + '\\', + ) + expect(response).toContain( + isWindows ? 'HTTP/1.1 403 Forbidden' : 'HTTP/1.1 404 Not Found', + ) + }) + test('should deny request with /@fs/ to denied file when a request has /.', async () => { const response = await sendRawRequest( viteTestUrl,
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
4News mentions
0No linked articles in our index yet.