VYPR
Medium severityOSV Advisory· Published Oct 20, 2025· Updated Apr 15, 2026

CVE-2025-62522

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.

PackageAffected versionsPatched versions
vitenpm
>= 7.1.0, < 7.1.117.1.11
vitenpm
>= 7.0.0, < 7.0.87.0.8
vitenpm
>= 6.0.0, < 6.4.16.4.1
vitenpm
>= 2.9.18, < 5.4.215.4.21
vitenpm
>= 3.2.9, < 5.4.215.4.21
vitenpm
>= 4.5.3, < 5.4.215.4.21
vitenpm
>= 5.2.6, < 5.4.215.4.21

Affected products

1
  • Range: create-vite@5.3.0, create-vite@5.4.0, create-vite@5.5.0, …

Patches

1
f479cc57c425

fix(dev): trim trailing slash before `server.fs.deny` check (#20968)

https://github.com/vitejs/viteOct 20, 2025via ghsa
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

4

News mentions

0

No linked articles in our index yet.