· 9 min read · Nadeera Silva
Vite Vulnerability GHSA-p4f5-76q4-ffq7: Patch the Dev Server RCE
A critical Vite vulnerability lets anyone who can reach an exposed dev server read files and run code. Here is who is affected and which version fixes it.

A new Vite vulnerability published on 10 November 2026 lets anyone who can reach your Vite dev server read files from your machine and run code on it. The advisory, GHSA-p4f5-76q4-ffq7, is rated Critical (CVSS 4.0 score 9.1) and covers every Vite release from 4.0.0 up to 8.3.6, plus the vite-plus toolchain up to 1.5.0. The good news is that the trigger is narrow: your dev server has to be exposed to the network. This post explains who is affected, which version to move to, and how to check a project in a few minutes.
What the Vite vulnerability does
Vite's resolver has two internal virtual modules, __vite-browser-external:<suffix> and __vite-optional-peer-dep:<suffix>. According to the advisory, both embedded the module ID, which comes straight from the request URL, into generated module code without escaping it. Because the suffix can be anything, a crafted request could inject arbitrary code into that module.
Vite trusts its own virtual modules, and that trust turned the injection into two separate problems:
- Arbitrary file read. Files imported by a trusted module pass the `server.fs` allow-list check. Injecting
import '/path/to/secret'pulls a file from outside your project into the module graph, and a follow-up request downloads it. The advisory's proof of concept shows a file that returns 403 before the injection and its full contents after it. - Remote code execution. Vite uses
evalto read values out of module code fornew Workerandimport.meta.glob. Injected code reaches thatevaland runs inside the Node process. Vite hides some globals such asrequire, but the advisory notes this was never a security boundary and shows a bypass throughglobalThis.process.getBuiltinModule.

The vulnerability is tagged CWE-116 (improper encoding or escaping of output). Four researchers are credited as reporters on the advisory.
Who is affected (and who is not)
The advisory is explicit: only apps that expose the dev server to the network are affected, meaning you ran vite --host or set `server.host` in your config. The default is 'localhost', which other machines cannot reach.
In practice, these setups commonly expose the dev server, so check them first:
- Docker and dev containers. Inside a container, Vite has to listen on
0.0.0.0for the host to reach it, so manyDockerfileandcompose.yamlfiles use--host. If the port is published to all interfaces (-p 5173:5173), anyone on your network can reach it too. - Cloud dev machines and VMs. A dev server on a cloud VM with an open security group or firewall rule is reachable from the internet.
- Testing on a phone.
--hostis the usual way to open a local site on a real device over Wi-Fi. On a café, coworking or office network, everyone on that network can reach your laptop's port. - WSL2 and shared hosts. Port forwarding rules and shared build boxes can widen exposure further than you expect.
Production sites are a different story. The advisory only describes the dev server. Static files produced by vite build and served from a CDN or your own server are not listed as affected, but you should still update Vite so your next dev session is safe.
Fixed versions: which Vite security update to install
Here is the full mapping from the advisory, cross-checked with the npm registry on 11 November 2026.
| Package | Affected range | Upgrade to |
|---|---|---|
| vite 4.x to 6.x | 4.0.0 to 6.4.5 | 6.4.6 |
| vite 7.x | 7.0.0 to 7.3.7 | 7.3.8 |
| vite 8.0 and 8.1 | 8.0.0 to 8.1.6 | 8.1.7 |
| vite 8.2 | 8.2.0 to 8.2.4 | 8.2.6 (see note) |
| vite 8.3 | 8.3.0 to 8.3.6 | 8.3.7 or 8.3.8 |
| vite-plus | up to 1.5.0 | 1.5.1 or later |
Vite 4 and 5 are not getting their own patches. If you are still on one of those, the nearest fixed release is 6.4.6, which is a major upgrade. Follow the Vite migration guides one major at a time and run your test suite between steps.
A detail worth knowing for Vite 8: the vulnerable code lives in the Rolldown binary that Vite 8 uses internally. The advisory says the fix depends on Rolldown 1.2.17 for 8.3.7 and 8.2.5 and Rolldown 1.1.7 for 8.1.7. The 8.3.7 changelog and the published package.json actually pin rolldown: ~1.2.18, and Rolldown 1.2.17 never appears in the npm registry. Either way, if your lockfile resolves a patched Vite, you get the patched Rolldown with it. You only need to look at Rolldown yourself if you override it separately.
At the time of writing the latest stable release is Vite 8.3.8 (11 November 2026), a bug-fix release on top of 8.3.7.
How to check your project in two minutes
package.json is not enough. Vite is often a transitive dependency of Vitest, Storybook, Astro, SvelteKit, Nuxt, React Router and others, so the version that actually runs is whatever your lockfile resolved. Start with your package manager:
# npm
npm ls vite vite-plus --all
# pnpm
pnpm why vite
# yarn (berry)
yarn why viteFor a quick pass/fail across a repo, including nested copies, I use this small dependency-free script. It walks node_modules, prints every installed vite and vite-plus, and exits with code 1 if any of them is in an affected range, so you can drop it into CI as well.
// check-vite.mjs: list every installed vite / vite-plus and flag GHSA-p4f5-76q4-ffq7
// Usage: node check-vite.mjs [projectDir]
import { readdirSync, readFileSync, existsSync } from "node:fs";
import { join } from "node:path";
// [minInclusive, maxInclusive, fixedIn] from the advisory
const RANGES = {
vite: [
["4.0.0", "6.4.5", "6.4.6"],
["7.0.0", "7.3.7", "7.3.8"],
["8.0.0", "8.1.6", "8.1.7"],
["8.2.0", "8.2.4", "8.2.6"], // 8.2.5 was tagged but never reached npm
["8.3.0", "8.3.6", "8.3.7"],
],
"vite-plus": [["0.0.0", "1.5.0", "1.5.1"]],
};
const parse = (v) => v.split("-")[0].split(".").map(Number);
const cmp = (a, b) => {
const x = parse(a), y = parse(b);
for (let i = 0; i < 3; i++) if (x[i] !== y[i]) return x[i] - y[i];
return 0;
};
function* walk(dir, depth = 0) {
if (!existsSync(dir) || depth > 8) return;
for (const e of readdirSync(dir, { withFileTypes: true })) {
if (!e.isDirectory() || e.name === ".bin") continue;
const p = join(dir, e.name);
if (e.name.startsWith("@")) { yield* walk(p, depth); continue; }
const pkg = join(p, "package.json");
if (existsSync(pkg)) {
try {
const { name, version } = JSON.parse(readFileSync(pkg, "utf8"));
if (RANGES[name]) yield { name, version, path: p };
} catch {}
}
yield* walk(join(p, "node_modules"), depth + 1);
}
}
const root = process.argv[2] ?? ".";
let bad = 0, found = 0;
for (const { name, version, path } of walk(join(root, "node_modules"))) {
found++;
const hit = RANGES[name].find(([lo, hi]) => cmp(version, lo) >= 0 && cmp(version, hi) <= 0);
if (hit) { bad++; console.log(`VULNERABLE ${name}@${version} -> upgrade to ${hit[2]}+ (${path})`); }
else console.log(`ok ${name}@${version} (${path})`);
}
if (!found) console.log("No vite or vite-plus found under node_modules.");
process.exit(bad ? 1 : 0);I tested it against fresh installs of vite@8.3.6 (reported as vulnerable, exit code 1) and vite@8.3.8 (reported as ok, exit code 0) on Node 24.
Upgrade steps
- Update direct dependencies. Bump
viteto the fixed version for your line, for examplenpm install -D vite@^8.3.7, then reinstall and commit the lockfile. - Force transitive copies if needed. If a tool pins an older Vite, add an override and reinstall. npm uses
overrides, pnpm usespnpm.overrides, and Yarn usesresolutions:
{
"overrides": {
"vite": "^8.3.7"
}
}- Rebuild containers. A dev container image built last week still has the old
node_modules. Rebuild it without the cache so the new lockfile is installed. - Run the check again and confirm the script exits with 0.
- Restart every running dev server. The fix only applies to a process started after the upgrade.
If you also run Next.js on other projects, the Next.js November 2026 security release landed in the same week and is worth checking at the same time.
Reduce exposure even after patching
Patching closes this hole, but Vite's own advisory list shows the dev server keeps getting server.fs bypass reports. Several medium-severity ones were published in October 2026 alone. The dev server was built for convenience, not as a hardened service, so the safer default is to keep it off untrusted networks.
- Bind to localhost unless you need more. Leave
server.hostat its default. When you need device testing, bind to one specific LAN IP for that session instead of makinghost: truepermanent in your config. - Publish container ports on loopback only. Use
-p 127.0.0.1:5173:5173in Docker, or"127.0.0.1:5173:5173"in Compose, so only your own machine can reach the port. - Never open the dev port in a cloud firewall. Use SSH port forwarding (
ssh -L 5173:localhost:5173 your-vm) or your cloud provider's private tunnel to reach a remote dev server. - Keep `server.allowedHosts` explicit. The Vite docs warn that setting it to
trueopens the server to DNS rebinding. List only hostnames you control. - Do not put secrets in the dev user's reach that it does not need. Long-lived cloud keys in your home directory turn any file-read bug into a credential leak.
- Track advisories automatically. Turn on Dependabot or Renovate security updates, and add
npm audit --audit-level=high(or the check script above) to CI. If you are setting up a pipeline from scratch, my solo SaaS CI/CD guide shows where a dependency check fits.
Quick checklist
- Find every Vite and vite-plus version that actually runs (
npm ls vite --allor the script). - Upgrade to 6.4.6, 7.3.8, 8.1.7, 8.2.6 or 8.3.7 and later, matching your line. vite-plus to 1.5.1 or later.
- Add overrides for tools that pin an older Vite.
- Rebuild dev containers and restart every dev server.
- Remove permanent
--hostandhost: truesettings, and publish container ports on 127.0.0.1. - If a dev server was exposed on an untrusted network, rotate the secrets that user account could read.
This one is quick to fix once you know where Vite is hiding in your dependency tree. Do the version check today, especially on any machine where a dev server has been running with --host.
Frequently asked questions
What is GHSA-p4f5-76q4-ffq7?
It is a critical Vite advisory published on 10 November 2026. A crafted request to an exposed Vite dev server can inject code into internal virtual modules, which lets an attacker read files outside the allow list and run code on the developer's machine.
Which Vite versions are affected by the vulnerability?
Vite 4.0.0 to 6.4.5, 7.0.0 to 7.3.7, 8.0.0 to 8.1.6, 8.2.0 to 8.2.4 and 8.3.0 to 8.3.6, plus vite-plus up to 1.5.0. The fixed versions are 6.4.6, 7.3.8, 8.1.7, 8.2.6 (8.2.5 never reached npm), 8.3.7 and vite-plus 1.5.1.
Am I affected if I only run vite on localhost?
According to the advisory, no. Only dev servers exposed to the network with --host or the server.host option are affected. You should still upgrade so a later --host session is safe.
Does the Vite vulnerability affect my production site?
The advisory describes the dev server only. Static files built with vite build and served from a CDN or web server are not listed as affected.
Is there a CVE number for this Vite security issue?
Not at the time of writing on 11 November 2026. The advisory has no CVE ID yet, so use the GHSA ID GHSA-p4f5-76q4-ffq7 when searching or tracking it.
How do I check which Vite version my project really uses?
Run npm ls vite --all, pnpm why vite or yarn why vite, because Vite is often a transitive dependency of tools like Vitest or Storybook. The check script in this post also walks node_modules and exits with code 1 if any copy is affected.
Sources
- Remote code execution using __vite-browser-external virtual module (GHSA-p4f5-76q4-ffq7) (Vite on GitHub, 2026-11-10)
- vite package metadata and publish times (npm registry)
- Vite v8.3.7 release notes (Vite on GitHub, 2026-11-09)
- Vite v8.3.8 release notes (Vite on GitHub, 2026-11-11)
- Vite 8.2.6 changelog (Vite on GitHub, 2026-11-09)
- Vite server options (server.host, server.allowedHosts, server.fs) (Vite)
- Vite security advisories (Vite on GitHub)
- Vite migration guide (Vite)
Keep reading
- Next.js Security Release November 2026: Upgrade to 16.4.5Next.js 16.4.5 and 15.5.29 fix seven vulnerabilities in use cache, Edge cookies, image optimization and self-hosting. Here's who is affected and how to patch.
- GitHub Actions CI/CD for a Solo SaaS: Tests, SSH Deploy and Prisma MigrationsThe GitHub Actions pipeline I run for Pactroom: tests, build, SSH deploy to a VPS, prisma migrate deploy and a health check, with a workflow you can adapt.
- Node 26 LTS: How to Upgrade from Node 22 or 24Node 26 became Active LTS on 28 October 2026. Compare Node 22, 24 and 26, then upgrade a Fastify or Express API with Prisma, Docker and CI.
Comments
Share a question or note about this article.
Loading comments…