GHSA-39r7-wfcx-99xg: 
JavaScript Analyse et atténuation de la vulnérabilité

Summary

The route cache in nitropack 2.x (defineCachedEventHandler, also used for the cache, swr and isr route rules) did not take the HTTP method into account. It also stored and replayed per-user response headers. As a result:

  1. A POST (or any other method) to a cached URL could store its response under the same key a later GET reads. Every user then received that response until it expired. In the other direction, a POST to a cached URL was answered from the cached GET entry and its handler never ran.
  2. Set-Cookie headers set by a cached handler were stored in the cache and sent to every user served from that entry. This leaks session identifiers and allows session fixation.
  3. A handler's Cache-Control: private, no-store or no-cache was ignored. The response was still cached and served to other users, and the header was rewritten to a shared-cacheable value (s-maxage=… / max-age=…), so CDNs in front of the app could cache it too.
  4. A response Vary header was ignored when storing and serving entries.

Details

defineCachedEventHandler in src/runtime/internal/cache.ts built its cache key only from the request path (including the query string) and the optional varies request headers. The method was never consulted, and the wrapper had no method guard, so all methods for a URL shared one entry. Handlers wrapped by a cache/swr/isr route rule all share the nitro/routes group, so the per-URL key is the only separation. After the handler ran, all response headers (including set-cookie) were stored in the entry. The wrapper then replayed them on every cache hit, appending set-cookie to each response. The wrapper also always overwrote cache-control with values derived from maxAge/swr, regardless of what the handler set. The response Vary header was not consulted either. A response that varies on a request header not listed in varies (for example Accept-Language or Authorization) was stored under one key and served to all clients. Request coalescing made the cookie issue worse: concurrent requests for the same key share one handler invocation, so they also shared its per-user response.

Proof of concept

// nitro.config.ts
export default defineNitroConfig({
  routeRules: {
    "/cached": { cache: { maxAge: 60 } },
  },
});
// routes/cached.ts
export default defineEventHandler((event) => {
  // e.g. a session cookie issued during render
  setCookie(event, "sid", crypto.randomUUID());
  return { method: event.method, renderedAt: Date.now() };
});
npx nitropack build && node .output/server/index.mjs &

# 1. attacker
curl -i -X POST http://localhost:3000/cached

# 2. any other user, for the next 60s
curl -i http://localhost:3000/cached

Step 2 returns the cached POST response ("method": "POST") together with the attacker's Set-Cookie: sid=….

Impact

  • Cache poisoning / wrong responses: an unauthenticated attacker can fill a cached route's entry with the response to a non-GET request, which all users then receive for the maxAge window (plus any stale-while-revalidate period). The attacker's control over the content is limited: request headers are stripped and the body is not passed. Side-effecting POST/PUT/DELETE requests to cached URLs silently return the cached body and never run.
  • Session leakage / fixation: any cached route whose handler sets a cookie (for example a session, CSRF or locale cookie set during Nuxt SSR on an swr/isr page) sends that cookie to every subsequent visitor.
  • Private data in shared caches: responses explicitly marked private/no-store/no-cache, or varying on request headers via Vary, were cached by Nitro and served to other users. Responses were also advertised as cacheable to downstream CDNs. This affects nitropack v2, including Nuxt 3 and 4 apps that use swr/isr/cache route rules. Applications that do not use defineCachedEventHandler/cachedEventHandler or the cache/swr/isr route rules are not affected.

Patches

Fixed in nitropack 2.13.6:

  • Only GET and HEAD requests read or write the cache. Other methods (and Range requests) always run the handler.
  • Responses that set cookies are never stored, and Set-Cookie is only sent to the request that produced it.
  • Responses with Cache-Control: private, no-store or no-cache are never stored, and the handler's own Cache-Control is kept.
  • Responses whose Vary is * or names a request header not listed in varies are never stored.

Workarounds

If you cannot upgrade:

  • don't set cookies or return per-user data from cached handlers or from routes with cache/swr/isr rules;
  • reject non-GET/HEAD requests to cached routes at your CDN, reverse proxy or in a middleware that runs before the cached handler.

Source: NVD

Connexe JavaScript Vulnérabilités :

CVE ID

Gravité

Partition

Technologies

Nom du composant

Exploit CISA KEV

A corrigé

Date de publication

GHSA-rhhp-7488-3qwfMEDIUM6.5
  • JavaScript logoJavaScript
  • nitropack
NonOuiNov 02, 2026
GHSA-pqxc-r4h5-jc95MEDIUM6.1
  • JavaScript logoJavaScript
  • nitropack
NonOuiNov 02, 2026
GHSA-39r7-wfcx-99xgMEDIUM4.8
  • JavaScript logoJavaScript
  • nitropack
NonOuiNov 02, 2026
GHSA-xrjv-fc7j-8f77HIGHN/A
  • JavaScript logoJavaScript
  • @graphql-tools/batch-execute
NonNonNov 02, 2026
GHSA-7p5p-67m9-5c8jHIGHN/A
  • JavaScript logoJavaScript
  • @graphql-tools/executor-http
NonNonNov 02, 2026

Évaluation gratuite des vulnérabilités

Évaluez votre posture de sécurité cloud

Évaluez vos pratiques de sécurité cloud dans 9 domaines de sécurité afin d’évaluer votre niveau de risque et d’identifier les lacunes dans vos défenses.

Évaluation de la demande

Ressources Wiz supplémentaires

Obtenez une démo personnalisée

Prêt(e) à voir Wiz en action ?

"La meilleure expérience utilisateur que j’ai jamais vue, offre une visibilité totale sur les workloads cloud."
David EstlickRSSI
"Wiz fournit une interface unique pour voir ce qui se passe dans nos environnements cloud."
Adam FletcherChef du service de sécurité
"Nous savons que si Wiz identifie quelque chose comme critique, c’est qu’il l’est réellement."
Greg PoniatowskiResponsable de la gestion des menaces et des vulnérabilités