OFFSITE.DARK
← Signals

Jul 1, 2026

2 min

Exploitarium

  • nextjs
  • cache
  • exploitarium

news

Next.js unstable_cache Object Argument Cache-Key Collision

Passing Request, URLSearchParams, or FormData into unstable_cache() collapses cache keys to {} while callbacks read live per-request data — first writer wins across restarts.

Summary

unstable_cache() on Next.js 16.3.0-canary.70 derives cache keys from JSON.stringify() of object arguments, which serializes Request, URLSearchParams, and FormData to {} even though the cached callback reads cookies, query values, and form fields from the live object. Distinct requests therefore share one Data Cache entry with first-writer semantics, persisting across next start restarts. This proof-of-concept is one of 30 folders in the Exploitarium collection. OFFSITE.DARK summarizes the upstream README and PoC design; we did not discover or weaponize this flaw.

Key Findings

FindingDetail
Product / targetNext.js 16.3.0-canary.70 (next build + next start)
PrimitiveObject argument cache-key collision via JSON.stringify{}
ImpactCross-user cache bleed for routes that pass request wrapper objects into unstable_cache() instead of extracted primitives.

Attack Chain

alice request → unstable_cache(Request) stores alice cookie → bob request same cache group → returns alice values → restart next start → charlie still sees alice

Mitigation

Never pass Request, URLSearchParams, or FormData objects as unstable_cache arguments; extract primitive cache-key components first; audit Data Cache usage on multi-tenant routes.

Related Signals

Sources

→ Source