A development server is not a staging environment, and it will hand your .env to anyone who asks the right way. F5 reports a mass-scanning campaign against internet-exposed Vite dev servers that systematically requests environment files, AWS credential files, Azure tokens and Terraform state. The underlying flaw, CVE-2026-39364, was fixed in April 2026. The scanning is what is new.
This matters beyond the Vite ecosystem. The files being requested are the files that most teams treat as the boundary between “our code is public” and “our cloud account is ours.” When that boundary is a plaintext file inside a directory a dev server is willing to read, a single access-control bug turns a convenience into a credential disclosure.
What is confirmed
The Vite project's advisory describes CVE-2026-39364 as a server.fs.deny bypass: files the deny list is supposed to block can be returned over HTTP when a query parameter such as ?raw, ?import&raw or ?import&url&inline is appended. The server treats the request as a valid asset fetch and responds with the file contents and an HTTP 200. No authentication is required. The GitHub Advisory Database lists it at CVSS 8.2 (high), published April 6, 2026, under CWE-180 and CWE-284.
The affected ranges are npm vite 7.1.0 through 7.3.1 and 8.0.0 through 8.0.4; the fixed releases are 7.3.2 and 8.0.5. The advisory is explicit that an application is affected only when all three conditions hold: the dev server is deliberately exposed to the network with --host or the server.host option, the sensitive file sits inside a directory allowed by server.fs.allow, and the file is one the project blocked through server.fs.deny. That last condition is worth reading twice: the bug affects files you had already decided were sensitive enough to deny.
F5 reports that its honeypot sensors recorded 807 session-grouped attacks and roughly 32,000 raw events during an August 2026 analysis window, against 1,732 Vite-related file-read events over the preceding three months. F5 says the scanning fleet cycled through wordlists rather than requesting a single path: .env and its .local, .production and .staging variants, AWS credential and config files in several common home directories, terraform.tfstate, serverless.yml, Azure credential and access-token files, and process-environment paths such as /proc/self/environ. F5 attributes most of the traffic to Google Cloud address ranges and reports that the same infrastructure also tested older Vite access-control bypasses, which suggests a broad exploit library rather than a single-vulnerability tool.
What remains unknown
F5's report documents scanning and file-read attempts. It does not establish that any particular organization's credentials were retrieved, which victims were reachable, or that any stolen key was subsequently used in a cloud account. Nobody has published a victim count. A honeypot measures what attackers try, not what they got.
This is also not a zero-day. The fix has been available since April 2026, and the scanning campaign F5 describes came months later. That distinction changes the response: the question is not “is there a patch” but “how long was a dev server listening on a public interface, and what was readable from it during that time.”
What to do this week
- Upgrade Vite to 7.3.2 or 8.0.5 (or later) everywhere, including sample apps, internal tools and the abandoned prototype nobody owns.
- Stop binding dev servers to external interfaces. Treat
--hostandserver.hostas a deliberate exception that needs a reason, not a default for “so I can test on my phone.” Use an SSH tunnel or an authenticated tunnel service instead. - Check exposure, not just configuration. Look for anything answering on the dev-server port from outside your network, and search access logs and proxy logs for requests containing
/@fs/or the?rawand?import&rawparameter patterns. - Assume disclosure if a server was publicly reachable during the period in question, and rotate what that host could read. F5 recommends exactly this for servers externally reachable during August 2026.
- Rotate in dependency order. Cloud provider keys first, then anything those keys could unlock: database passwords, third-party API tokens, webhook signing secrets, and any Terraform state that contained values rather than references.
The part most teams get wrong: handing over the replacement
Rotation is only half the work. The new AWS key has to reach the developer, the CI system and the on-call engineer who needs it at 23:00. In practice, that is where the freshly rotated credential goes straight back into a chat thread, a ticket comment or an email, and the organization ends up with a second copy of the secret in a system with long retention and broad search.
Decide the handover path before you start rotating, not while you are in the middle of it:
- Prefer no handover at all. A workload identity, an OIDC federation to your CI provider, or a short-lived role assumption removes the long-lived key that needed distributing in the first place. This is the only change that makes the next incident smaller.
- Where a human must receive a value, send it through a channel that expires, rather than one that archives. A one-time link keeps the value out of the persistent record even if the recipient's mailbox is later exported.
- Never put the rotated secret in the same ticket that documents the incident. Incident tickets get shared widely, attached to postmortems and read by people who joined afterwards.
- Split high-value material. For a root-account recovery code or a break-glass credential, require more than one person to reconstruct it, so a single compromised mailbox is not enough.
Why .env keeps showing up in these reports
Every campaign of this shape converges on the same wordlist because the answer is usually there. A plaintext file in the project directory is readable by the dev server, the test runner, an editor extension, a postinstall script and any process running as that user. It survives in shell history when it is copied, in backups when the laptop is imaged, and in container layers when it is added a step too early.
You do not have to eliminate .env to improve this. Reducing what it contains is enough to change the outcome: keep non-secret configuration in it, move actual credentials to a secrets manager or a short-lived token, and make sure that the worst case of a readable .env is an inconvenience rather than a cloud takeover.
Where Secretus fits—and where it does not
Secretus can reduce plaintext exposure when an authorized person must deliver a small, temporary value—a rotated API key, a recovery code, a one-off access credential—over a channel that does not retain it the way chat and email do. Team Split can require several holders to reconstruct a high-value text secret such as a break-glass code.
It is not a secrets manager, not a replacement for workload identity, and not a place to store your .env. It does not tell you whether your dev server was reachable or whether anything was read from it. Use your cloud provider's logs for that question, patch Vite for the cause, and use a one-time channel only for the narrow step of getting a replacement value to the person who needs it.
