GHSA-2vc4-c4r6-p6v6

Suggest an improvement
Source
https://github.com/advisories/GHSA-2vc4-c4r6-p6v6
Import Source
https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/10/GHSA-2vc4-c4r6-p6v6/GHSA-2vc4-c4r6-p6v6.json
JSON Data
https://api.osv.dev/v1/vulns/GHSA-2vc4-c4r6-p6v6
Aliases
Published
2026-10-15T20:15:17Z
Modified
2026-10-15T20:30:05Z
Severity
  • 7.5 (High) CVSS_V3 - CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N CVSS Calculator
Summary
OpenNext Cloudflare: Cache interception can bypass middleware protection for encoded paths
Details

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.

Database specific
{
    "cwe_ids":  [
        "CWE-177",
        "CWE-180"
    ],
    "github_reviewed":  true,
    "github_reviewed_at":  "2026-10-15T20:15:17Z",
    "nvd_published_at":  "2026-10-15T17:17:07Z",
    "severity":  "HIGH"
}
References

Affected packages

npm / @opennextjs/cloudflare

Package

Name
@opennextjs/cloudflare
View open source insights on deps.dev
Purl
pkg:npm/%40opennextjs/cloudflare

Affected ranges

Type
SEMVER
Events
Introduced
0.3.0
Fixed
1.20.2

Database specific

source
"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/10/GHSA-2vc4-c4r6-p6v6/GHSA-2vc4-c4r6-p6v6.json"