All vulnerabilities
CVE-2026-100409GHSA-2vc4-c4r6-p6v6

@opennextjs/cloudflare: OpenNext Cloudflare: Cache interception can bypass middleware protection for encoded paths

opennextjs @opennextjs/cloudflarenpmLibraries & packages
CVSS
7.5High
ExploitationNo known exploitationNot in CISA KEV, which does not prove it is unexploitedCISA KEV
Exploit odds (EPSS)0.30%Chance of exploitation activity in the next 30 days, higher than 22% of CVEs. Scored 23 Oct 2026FIRST EPSS
Fixed in1.20.2Fixed versionGitHub
Published15 Oct 2026Updated 15 Oct 2026CVE List

What fixes it

  • 1.20.2@opennextjs/cloudflare, npmGitHubnpm install @opennextjs/cloudflare@1.20.2

A fixed version on one release line is not the upgrade target for every line. Check your exact version and any vendor backports.

Description

Summary

When cache interception is enabled, @opennextjs/cloudflare can interpret percent-encoded paths differently during middleware matching and cache lookup.

An encoded request may fail to match authorization middleware, then be decoded into the cache key of a protected route. The cached response may consequently be returned without invoking the middleware.

enableCacheInterception is disabled by default.

Impact

A remote unauthenticated attacker may retrieve cached content from routes intended to be protected by middleware.

An application is affected when it:

  • explicitly enables enableCacheInterception;
  • relies on middleware for access control; and
  • has a matching cached route.

Details

Middleware matching previously used the encoded request pathname, while cache interception decoded the pathname before selecting a cache entry.

For example, consider an application with:

  • middleware matcher /admin/:path*;
  • middleware returning 401 Authentication required for /admin;
  • a statically generated, cached /admin route; and
  • cache interception enabled:
export default defineCloudflareConfig({
  incrementalCache: staticAssetsIncrementalCache,
  enableCacheInterception: true,
});

An attacker can request:

GET /%61dmin

The encoded pathname does not match /admin/:path*, so the authorization middleware is not invoked. Cache interception then decodes %61dmin to admin and may return the cached /admin response:

HTTP/1.1 200 OK
x-opennext-cache: HIT

Protected content

Malformed paths exposed an additional inconsistency. For example:

GET /%61dmin/%ZZ

The previous implementation decoded each segment independently. It decoded %61dmin to admin but retained the malformed %ZZ segment, allowing cache lookup to continue using a partially decoded pathname.

Patches

The fix aligns encoded-path handling across middleware matching and cache lookup, and rejects malformed paths instead of partially decoding them. See the upstream fixes in opennextjs-aws#1199 and opennextjs-aws#1200.

Users should upgrade to @opennextjs/cloudflare@1.20.2 or later.

Workarounds

If upgrading is not immediately possible for an application:

  1. Disable cache interception by removing enableCacheInterception: true.
  2. Enforce authorization inside protected route handlers rather than relying exclusively on middleware.
  3. Reject encoded paths for protected routes at a trusted proxy before they reach the Worker.

Adding individual encoded matcher variants is not a complete workaround because pathnames can have multiple equivalent encodings.

Text from GitHub Advisory Database

Affected versions 3

  • @opennextjs/cloudflare, npm>= 0.3.0, < 1.20.2GitHub
  • opennextjs-cloudflareaffected: >= 0.3.0, < 1.20.2CVE List
  • @opennextjs/cloudflare, npmfrom 0.3.0, fixed in 1.20.2OSV

References 7