CVE-2025-58751: Vite Vite Middleware May Serve Files Vulnerability
LOWCVE-2025-58751 is a LOW vite middleware may serve files vulnerability (CWE-284: Improper Access Control) affecting Vite libraries in the npm ecosystem. The issue involves vite middleware may serve files starting with the same name with the public directory. Remediation is available by upgrading affected packages to version 7.1.5, 7.0.7, 6.3.6, 5.4.20.
CVE-2025-58751 at a Glance
How to Fix CVE-2025-58751
To remediate this vulnerability, upgrade all affected Vite dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.
npm install vite@7.1.5
npm install vite@7.0.7
npm install vite@6.3.6
npm install vite@5.4.20
Run the following command in your project directory to verify that all resolved dependencies use the patched release:
npm ls vite
How to Check if You Are Affected
To determine whether your Node.js application is affected by CVE-2025-58751, inspect your project dependencies using npm:
npm ls vite
Analyze the terminal output to locate any version of Vite in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 7.1.5), your application is affected.
Note: The npm ls vite command inspects dependencies declared in your package.json and lockfile; it does not perform automated runtime dynamic scanning.
Technical Details
Vulnerability Mechanism & Technical Analysis
This vulnerability is classified under CWE-284: Improper Access Control, where the product does not restrict or incorrectly restricts access to a resource from an unauthorized actor. In Vite, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.
Source Advisory Statement
CVE-2025-58751 Affected Vite Versions
4 component(s)References
Frequently Asked Questions
What is CVE-2025-58751?
Which Vite versions are affected?
What version fixes CVE-2025-58751?
Is vite affected?
What CWE is associated with CVE-2025-58751?
How can I check npm dependencies for CVE-2025-58751?
Machine-readable OSV JSON
OSV v1.5 Schema
{
"schema_version" : "1.4.0",
"id" : "GHSA-g4jq-h2w9-997c",
"modified" : "2025-09-09T20:55:56Z",
"published" : "2025-09-09T20:55:56Z",
"aliases" : [ "CVE-2025-58751" ],
"summary" : "Vite middleware may serve files starting with the same name with the public directory",
"details" : "### Summary\nFiles starting with the same name with the public directory were served bypassing the `server.fs` settings.\n\n### Impact\nOnly apps that match the following conditions are affected:\n\n- explicitly exposes the Vite dev server to the network (using --host or [`server.host` config option](https://vitejs.dev/config/server-options.html#server-host))\n- uses [the public directory feature](https://vite.dev/guide/assets.html#the-public-directory) (enabled by default)\n- a symlink exists in the public directory\n\n### Details\nThe [servePublicMiddleware](https://github.com/vitejs/vite/blob/9719497adec4ad5ead21cafa19a324bb1d480194/packages/vite/src/node/server/middlewares/static.ts#L79) function is in charge of serving public files from the server. It returns the [viteServePublicMiddleware](https://github.com/vitejs/vite/blob/9719497adec4ad5ead21cafa19a324bb1d480194/packages/vite/src/node/server/middlewares/static.ts#L106) function which runs the needed tests and serves the page. The viteServePublicMiddleware function [checks if the publicFiles variable is defined](https://github.com/vitejs/vite/blob/9719497adec4ad5ead21cafa19a324bb1d480194/packages/vite/src/node/server/middlewares/static.ts#L111), and then uses it to determine if the requested page is public. In the case that the publicFiles is undefined, the code will treat the requested page as a public page, and go on with the serving function. [publicFiles may be undefined if there is a symbolic link anywhere inside the public directory](https://github.com/vitejs/vite/blob/9719497adec4ad5ead21cafa19a324bb1d480194/packages/vite/src/node/publicDir.ts#L21). In that case, every requested page will be passed to the public serving function. The serving function is based on the [sirv](https://github.com/lukeed/sirv) library. Vite patches the library to add the possibility to test loading access to pages, but when the public page middleware [disables this functionality](https://github.com/vitejs/vite/blob/9719497adec4ad5ead21cafa19a324bb1d480194/packages/vite/src/node/server/middlewares/static.ts#L89) since public pages are meant to be available always, regardless of whether they are in the allow or deny list.\n\nIn the case of public pages, the serving function is [provided with the path to the public directory](https://github.com/vitejs/vite/blob/9719497adec4ad5ead21cafa19a324bb1d480194/packages/vite/src/node/server/middlewares/static.ts#L85) as a root directory. The code of the sirv library [uses the join function to get the full path to the requested file](https://github.com/lukeed/sirv/blob/d061616827dd32d53b61ec9530c9445c8f592620/packages/sirv/index.mjs#L42). For example, if the public directory is \"/www/public\", and the requested file is \"myfile\", the code will join them to the string \"/www/public/myfile\". The code will then pass this string to the normalize function. Afterwards, the code will [use the string's startsWith function](https://github.com/lukeed/sirv/blob/d061616827dd32d53b61ec9530c9445c8f592620/packages/sirv/index.mjs#L43) to determine whether the created path is within the given directory or not. Only if it is, it will be served.\n\nSince [sirv trims the trailing slash of the public directory](https://github.com/lukeed/sirv/blob/d061616827dd32d53b61ec9530c9445c8f592620/packages/sirv/index.mjs#L119), the string's startsWith function may return true even if the created path is not within the public directory. For example, if the server's root is at \"/www\", and the public directory is at \"/www/p\", if the created path will be \"/www/private.txt\", the startsWith function will still return true, because the string \"/www/private.txt\" starts with \"/www/p\". To achieve this, the attacker will use \"..\" to ask for the file \"../private.txt\". The code will then join it to the \"/www/p\" string, and will receive \"/www/p/../private.txt\". Then, the normalize function will return \"/www/private.txt\", which will then be passed to the startsWith function, which will return true, and the processing of the page will continue without checking the deny list (since this is the public directory middleware which doesn't check that).\n\n### PoC\nExecute the following shell commands:\n\n```\nnpm create vite@latest\ncd vite-project/\nmkdir p\ncd p\nln -s a b\ncd ..\necho 'import path from \"node:path\"; import { defineConfig } from \"vite\"; export default defineConfig({publicDir: path.resolve(__dirname, \"p/\"), server: {fs: {deny: [path.resolve(__dirname, \"private.txt\")]}}})' > vite.config.js\necho \"secret\" > private.txt\nnpm install\nnpm run dev\n```\n\nThen, in a different shell, run the following command:\n\n`curl -v --path-as-is 'http://localhost:5173/private.txt'`\n\nYou will receive a 403 HTTP Response, because private.txt is denied.\n\nNow in the same shell run the following command:\n\n`curl -v --path-as-is 'http://localhost:5173/../private.txt'`\n\nYou will receive the contents of private.txt.\n\n### Related links\n- https://github.com/lukeed/sirv/commit/f0113f3f8266328d804ee808f763a3c11f8997eb",
"severity" : [ {
"type" : "CVSS_V4",
"score" : "CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N"
} ],
"affected" : [ {
"package" : {
"ecosystem" : "npm",
"name" : "vite"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "7.1.0"
}, {
"fixed" : "7.1.5"
} ]
} ],
"database_specific" : {
"last_known_affected_version_range" : "<= 7.1.4"
}
}, {
"package" : {
"ecosystem" : "npm",
"name" : "vite"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "7.0.0"
}, {
"fixed" : "7.0.7"
} ]
} ],
"database_specific" : {
"last_known_affected_version_range" : "<= 7.0.6"
}
}, {
"package" : {
"ecosystem" : "npm",
"name" : "vite"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "6.0.0"
}, {
"fixed" : "6.3.6"
} ]
} ],
"database_specific" : {
"last_known_affected_version_range" : "<= 6.3.5"
}
}, {
"package" : {
"ecosystem" : "npm",
"name" : "vite"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "0"
}, {
"fixed" : "5.4.20"
} ]
} ],
"database_specific" : {
"last_known_affected_version_range" : "<= 5.4.19"
}
} ],
"references" : [ {
"type" : "WEB",
"url" : "https://github.com/vitejs/vite/security/advisories/GHSA-g4jq-h2w9-997c"
}, {
"type" : "ADVISORY",
"url" : "https://nvd.nist.gov/vuln/detail/CVE-2025-58751"
}, {
"type" : "WEB",
"url" : "https://github.com/lukeed/sirv/commit/f0113f3f8266328d804ee808f763a3c11f8997eb"
}, {
"type" : "WEB",
"url" : "https://github.com/vitejs/vite/commit/09f2b52e8d5907f26602653caf41b3a56692600d"
}, {
"type" : "WEB",
"url" : "https://github.com/vitejs/vite/commit/4f1c35bcbb5830290c694aa14b6789e07450f069"
}, {
"type" : "WEB",
"url" : "https://github.com/vitejs/vite/commit/63e2a5d232218f3f8d852056751e609a5367aaec"
}, {
"type" : "WEB",
"url" : "https://github.com/vitejs/vite/commit/e11d24008b97d4ca731ecc1a3b95260a6d12e7e0"
}, {
"type" : "PACKAGE",
"url" : "https://github.com/vitejs/vite"
} ],
"database_specific" : {
"cwe_ids" : [ "CWE-200", "CWE-22", "CWE-284" ],
"severity" : "LOW",
"github_reviewed" : true,
"github_reviewed_at" : "2025-09-09T20:55:56Z",
"nvd_published_at" : "2025-09-08T23:15:36Z"
}
}