The Hacker News ran the story on September 15: a mass-scanning campaign is pulling AWS and Azure credentials out of exposed Vite dev servers. The bug is CVE-2026-39364. Vite published it on April 6 and shipped the fix the same day. Five months later the exploitation curve is going up, not down.
My first reaction was to check my own machine, and that turned out to be the more interesting half of the story.
Four Advisories in a Day
April 6 was a bad day for Vite’s dev server. Three advisories landed together, and a fourth followed on June 1.
- CVE-2026-39364, the query bypass. The access check ran against the full URL, query string included. So
/@fs/.envgot a 403, and/@fs/.env?rawgot a 200. Affects 7.1.0 to 7.3.1 and 8.0.0 to 8.0.4. Fixed in 7.3.2 and 8.0.5. - CVE-2026-39363, the WebSocket read. The HMR socket exposed a
fetchModulecall that skipped theserver.fschecks entirely. Connect without an Origin header, ask for afile://URL with?raw, and you get the file back as a JavaScript string. Affects 6.0.0 onwards. Same fix versions. - CVE-2026-39365, source maps for optimized deps. Path traversal through
.maprequests. Moderate. Same fix versions. - CVE-2026-53571, Windows alternate paths.
/.env::$DATA?rawand 8.3 short names got past the deny list on NTFS. Fixed in 6.4.3, 7.3.5 and 8.0.16.
Every one of them carries the same clause: only apps that expose the server with --host or server.host are affected. That clause is true. It is also the part of the advisory doing the most work, and it deserves a closer look.
The Wordlist Knows Where You Are
F5 Labs published the telemetry. In the three months before August, its sensors saw 1,732 events. In August alone: 807 grouped attacks and about 32,000 raw events. The traffic comes mostly from Google Cloud ranges, the User-Agent strings claim to be Googlebot, ClaudeBot, GPTBot, PerplexityBot and Amazonbot, and the X-Forwarded-For headers are forged.
The requests look like this:
GET /@fs/.env?raw??
GET /@fs/..%252f..%252f..%252f..%252froot/.env?raw??
GET /@fs/..%252f..%252f..%252f..%252fproc/self/environ?raw??
Then the wordlist. It asks for .env and its .local, .production and .staging variants. It asks for .aws/credentials under /root, /home/ec2-user, /home/ubuntu, /home/node, /usr/src/app and /app. It asks for terraform.tfstate, serverless.yml, .azure/accessTokens.json, /etc/passwd and /proc/1/environ.
Read those paths as a description of the victim. /home/node is the default user in the official Node Docker image. /usr/src/app and /app are the two most-copied WORKDIR lines on the internet. /home/ec2-user is an AWS VM. /proc/1/environ only pays off when PID 1 is your process, which means a container. Nobody is scanning for laptops.
— F5 Labs, September 2026The scanner’s focus on cloud credentials, IaC states, and process memory files indicates threat actors prioritize rapid access to cloud provider infrastructure over application-level compromise.
That is the reframe. The --host clause reads as reassurance: the default is localhost, so most people are safe. But --host is not a choice people make carelessly. It is the flag you must set the moment the dev server runs anywhere but your own machine, because a container’s localhost is unreachable from outside it. Every Docker dev setup, every cloud dev box, every agent sandbox that hands you a preview URL has set it. The advisory’s exception is the deployment pattern of the decade.
Auditing My Own Machine
One command finds every installed copy:
find ~/Projects -path '*/node_modules/vite/package.json' \
-exec grep -H '"version"' {} +
The results, across everything I have cloned:
- 47 repos pin Vite in a lockfile.
- 28 pin a version with at least one 2026 CVE. The most common stale pins were 7.3.1 and 6.4.1, both one patch release short.
- 10 have that version installed in
node_modules, ready to run. Four of those are checkouts of the same project. - 0 dev servers were listening when I looked, and none of the stale repos passes
--hostin its dev script. - 6 repos deliberately reach past localhost through ngrok, Tailscale or a custom domain for remote work. All six were already on patched versions.
So the honest answer is: not exposed, by default and by luck rather than by process. Two things in the audit bothered me anyway.
One personal project had server.allowedHosts: true in its Vite config. I set it months ago to test through a tunnel and never removed it. That setting disables Vite’s Host header check, which is the defence against DNS rebinding: a malicious page in your browser resolves its own domain to 127.0.0.1 and talks to your localhost dev server. With a patched Vite that gets you nothing. With the 7.3.1 that repo was pinned to, it gets you ?raw on every file the dev server can see, without --host ever being set. The advisory’s exception did not cover that case. My config did.
The second is Vitest. Several repos had Vite patched at the top level and a second, older Vite nested under node_modules/vitest. Vitest runs its own Vite server, and a bun update vite does not touch it.
What This Doesn’t Settle
- Vite’s defaults are right. Localhost bind, a deny list that covers
.envand certificates, and a Host allowlist that ships on. The bugs were in the enforcement, and the team fixed them the day they published. - F5 sees its own customers, not the internet. 32,000 events is the view from one vendor’s sensors. The real number is larger and unknown.
- Only the query bypass has a public campaign. The WebSocket bug is arguably worse, since it ignores
server.fsentirely, but nobody has published exploitation numbers for it. - Lockfile counts overstate risk. A stale pin in a side project with no
node_modulescannot serve anything. The ten installed copies are the number that matters, and the one withallowedHosts: trueis the number that matters most.
The Takeaway
- Read the wordlist, not the CVSS. The attacker’s file paths tell you who they expect to hit. These expect containers with cloud credentials mounted next to the source.
- The “only with —host” clause describes the target, not the exception. Every remote dev environment sets it. If your agent sandbox or dev container gives you a preview URL, assume it is set.
- Audit config, not just versions.
allowedHosts: trueandhost: 0.0.0.0are one-line changes made for a tunnel one afternoon. They outlive the afternoon. - Check nested copies. Vitest, Astro and the framework plugins carry their own Vite. Patch the pin at the top and you may have patched nothing.
- Then rotate. F5’s advice for anyone who ran an unpatched, exposed server is not “update”. It is “update, then rotate every secret the server could read”. The scanners had five months.



