Nuxt dev server exposes private runtime config through the Nitro dev bundle
Impact
Nuxt dev server exposes private runtime config through the Nitro dev bundle, affecting Nuxt versions 3.0.0 to 4.6.3. Exploitation requires direct HTTP access to the dev server. Private runtime config values can be read by anyone with access.
Summarized by @cf/meta/llama-3.3-70b-instruct-fp8-fast. Verify details against the original sources.Exploitation requires direct HTTP access to the dev server.
Affected packages
Start with the recorded fix for your release branch. Check your installed version and test compatibility before upgrading. Fixing this advisory does not rule out other vulnerabilities in the release.
| Affected range | Recorded fix |
|---|---|
| From 3.0.0 before 4.6.3Semantic versions | 4.6.3 |
Version evidence: OSV · GHSA-648h-gw55-m2g7
View original version evidence (0 explicit versions)
Affected products
Vendor version evidence. Product records are separate from automatic dependency matching.
nuxt · GitHub_M
nuxt
1 range
nuxt · GitHub_M
nuxt
Compare with this publisher’s ranges. This does not inspect your installation.
affected
>= 3.0.0, < 4.6.3
Other versions: unknown
Original source description
Summary
With Nitro 2 (the default server engine in Nuxt 3 and Nuxt 4), the Nitro development server bundle written by nuxt dev can be fetched through the Vite dev server. Nitro inlines the resolved runtimeConfig into that bundle, so private runtime config values that were resolved at build time can be read by anyone with HTTP access to the dev server.
Impact
nuxt dev writes the Nitro development server bundle to <buildDir>/dev/index.mjs (by default .nuxt/dev/index.mjs). The build directory is inside the directories Nuxt passes to Vite's server.fs.allow, so the bundle is served by the dev server:
curl http://<dev-server>/_nuxt/@fs/<absolute-path-to-project>/.nuxt/dev/index.mjs
The response contains every private (non-public) runtime config value that was resolved at build time. That includes values set in nuxt.config, such as a secret read from .env:
export default defineNuxtConfig({
runtimeConfig: {
apiSecret: process.env.API_SECRET,
},
})
From Nuxt 4.6.0, it also includes the generated development appSecret. Vite's default deny list blocks .env itself, but not the bundle containing values read from it.
Exploitation requires direct HTTP access to the dev server. nuxt dev listens on localhost by default, so this mainly affects dev servers that are exposed to a network (for example with --host, a published container port or a tunnel). As far as we can tell, a malicious website cannot read the file through a developer's browser: Vite's CORS and host checks prevent pages on other origins from reading the response.
Production builds are not affected, because the Vite dev server is not used and the server bundle is not served. Nuxt projects using Nitro 3 do not write the server bundle to disk in development and are not affected. Private runtime config values that are left empty in nuxt.config and supplied through NUXT_* environment variables are applied when the server starts, are not inlined into the bundle, and are not exposed.
Patches
Fixed in @nuxt/vite-builder 4.6.3, which nuxt 4.6.3 depends on. The dev server now adds Nitro's development output directory to Vite's server.fs.deny, keeping Vite's default deny list.
Nuxt 3 has reached end of life and will not receive a fix.
Workarounds
Avoid exposing the dev server to untrusted networks. Alternatively, set private runtime config keys to an empty default in nuxt.config and provide their values with the matching NUXT_* environment variables (for example runtimeConfig: { apiSecret: '' } with NUXT_API_SECRET in .env).
If a dev server has been reachable by untrusted clients, rotate any credentials that were set through runtimeConfig in nuxt.config.
Inside the record
Evidence available
Describes the evidence in this view, not whether the product is safe.
Original records
CVE-2026-119199View the latest unmodified CVE JSON from the official source. It may be newer than this imported page.
cve.new JSON →Underlying weaknesses
The source’s classification of what caused the vulnerability.
Contributing organizations · 2
Assigning organization
Additional data publisher
What changed
Follow changesLarge field values are marked as truncated previews. Original source snapshots remain retained.