
Cloud Vulnerability DB
A community-led vulnerabilities database
In @opennextjs/cloudflare up to 1.20.15, applications using staticAssetsIncrementalCache or withRegionalCache (with the R2 or KV incremental cache) can return a middleware-protected page for a double-encoded request path.
Middleware evaluates the encoded and once-decoded pathname, but subsequent cache-URL processing can resolve the request to a different, protected cache entry. This bypasses the protection added for GHSA-2vc4-c4r6-p6v6 (CVE-2026-100409).
Exploitation requires:
staticAssetsIncrementalCache: a prerendered entry.withRegionalCache: an entry in the regional cache (Cache API) of the data center that serves the request. It is stored there when an authorized request reads the page.enableCacheInterception both enabled and disabled.What happens with GET /%2561dmin:
/%2561dmin and /%61dmin). Neither matches /admin/:path*, so middleware does not run.enableCacheInterception is enabled) or the Next.js server (otherwise) decodes the path once (/%61dmin). No manifest route equals it, so the request is served by the catch-all route and the cache key is /route-cache/APP_PAGE/<sha>/$/%61dmin, with the percent escape still in it.StaticAssetsIncrementalCache.getAssetUrl puts that key into http://assets.local/cdn-cgi/_next_cache/<buildId>/<key>.cache without encoding it. The Workers assets binding decodes %61 again and returns the cache entry for /admin./admin is returned to the client: as a cache HIT (x-opennext-cache: HIT) from the interceptor, or as x-nextjs-cache: STALE from the Next.js server when interception is disabled.
The 1.20.2 fix made middleware and the cache interceptor decode the path the same way. Step 3 is an extra decode that nothing guards, and it is reached with or without the interceptor.withRegionalCache)withRegionalCache has the same flaw when it builds the Cache API URL (http://cache.local/<buildId>/<key>.cache) from the key. Here the extra processing comes from URL parsing, not from a binding: %2e%2e and %2e segments are resolved as dot segments.
With GET /secret/x/%252e%252e/admin, the cache key is .../$/secret/x/%2e%2e/admin, and its Cache API URL resolves to the URL of .../$/secret/admin:
An unauthenticated attacker may retrieve protected content available through the application’s static-assets incremental cache, or through the regional cache, without invoking the authorization middleware. Exposure is limited to existing entries reachable through the affected route and cache-key resolution. This does not establish access to arbitrary pages or content from other applications. With the regional cache, only entries currently in the Cache API of the data center serving the request are exposed. With the regional cache, an attacker can also replace a protected entry in the regional cache of a data center with the page rendered for the alias, until the entry expires. The replacement is rendered by the application for the same route. No availability impact has been demonstrated.
Source: NVD
Free Vulnerability Assessment
Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.
Get a personalized demo
"Best User Experience I have ever seen, provides full visibility to cloud workloads."
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
"We know that if Wiz identifies something as critical, it actually is."