Packages / @opennextjs/cloudflare / Security

HighVulnerabilityGHSA-2vc4-c4r6-p6v6CVE-2026-100409Published 15 Oct 2026

OpenNext Cloudflare: Cache interception can bypass middleware protection for encoded paths

Affected releases · @opennextjs/cloudflare

  • 1.x1.0.0 – 1.20.1Fixed in 1.20.2
  • 0.6.x and older0.3.0 – 0.6.6No fix, no longer updated

On 1.x, the newest line:

npm install @opennextjs/cloudflare@1.20.2
1.x
  1. Affected

    1.0.0 – 1.20.1

    79 releases

  2. Fixed

    1.20.2 – 1.20.12

    11 releases, latest

0.x
  1. Not affected

    0.0.3 – 0.2.1

    5 releases

  2. Affected

    0.3.0 – 0.6.6

    40 releases

135 stable releases of @opennextjs/cloudflare, oldest to newest, one row per major.

Is your project affected?

Paste your package.json, or type the range you declare for @opennextjs/cloudflare. It is read in your browser and sent nowhere.

What happens

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.