CVE-2026-64647
Executive Summary
CVE-2026-64647 is a cache poisoning vulnerability in Next.js, a popular React framework. When a server-side fetch() call includes a request body with a content‑type charset other than UTF‑8 (e.g., UTF‑16), the framework may incorrectly reuse a cached response from a different request to the same URL but with a different body. This leads to the leakage of confidential response data to unauthorized clients. The vulnerability affects Next.js versions 12.0.0 through 15.5.20 and 16.0.0 through 16.2.10. Patches were released in 15.5.21 and 16.2.11.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
Next.js is distributed as an npm package (next). Organizations using affected versions must update to the patched versions immediately. The vulnerability does not require any special privileges and can be triggered remotely by crafting a request with a non‑UTF‑8 charset. Software composition analysis (SCA) tools should flag next versions within the vulnerable ranges. Developers should ensure that their package.json and package-lock.json reference a secure version (^15.5.21 or ^16.2.11).
CVSS Breakdown & Threat Level
Although no official CVSS vector was assigned, the characteristics of CVE-2026-64647 align with a High severity score (estimated 7.5):
- Attack Vector: Network (remote exploitation possible)
- Attack Complexity: Low (no special conditions beyond charset manipulation)
- Privileges Required: None
- User Interaction: None
- Scope: Unchanged
- Confidentiality: High (sensitive response bodies leaked)
- Integrity: None
- Availability: None
The vulnerability allows an attacker to obtain data intended for other users by sending crafted POST requests with the same URL but different body encoding.
Deep Dive & Mechanics
Next.js uses an in‑memory cache for server‑side fetch() calls. When a fetch request has a body, the cache key is composed of the URL and a hash of the request body. The hash function used in vulnerable versions does not account for the charset of the body content.
The flaw:
If an attacker sends two requests to the same URL with bodies that are byte‑distinct under UTF‑8 but byte‑identical when interpreted in UTF‑16, the cache treats them as the same key. For example:
- Request A: POST
/api/datawith UTF‑8 body{"input":"hello"} - Request B: POST
/api/datawith UTF‑16 body (bytes that decode to a completely different string like"world")
Because the raw byte streams of the two bodies might collide after a charset‑sensitive normalization, the cache returns the response from Request A to the client of Request B, leaking data.
Affected flow:
- Server receives a POST request with a non‑UTF‑8 charset (e.g.,
Content-Type: application/json; charset=utf-16). - Next.js reads the body, hashes it using a charset‑blind algorithm.
- The hashed key matches an existing cache entry for a different request body.
- The cached response (potentially containing sensitive data) is returned to the current requestor.
Vulnerable vs. Patched Code
The fix addresses the charset collision by incorporating the charset into the cache key hash.
Vulnerable (pseudo‑code):
const bodyText = await request.text(); // charset ignored
const cacheKey = hash(url + hash(bodyText));
Patched:
const charset = request.headers['content-type'].match(/charset=([^;]+)/);
const bodyText = await request.text(); // still raw bytes
const cacheKey = hash(url + hash(charset) + hash(bodyText));
By including the charset string in the key, requests with different charsets produce different cache entries, even if the raw bytes coincide.
Exploitation & Lab Setup
Red Team
Goal: Extract sensitive response data (e.g., user profiles, tokens) from a Next.js application.
Prerequisites:
- Access to an affected Next.js server (versions 12.0.0 – 15.5.20 or 16.0.0 – 16.2.10).
- Ability to send POST requests with a custom
Content-Typecharset.
Step‑by‑step:
- Identify a fetch‑based endpoint that uses a request body (e.g.,
/api/searchwithPOST). - Craft two requests:
- Request A (legitimate user):
POST /api/searchwithContent-Type: application/json; charset=utf-8and body{"q":"admin"}⇒ receives admin data. - Request B (attacker):
POST /api/searchwithContent-Type: application/json; charset=utf-16and body bytes that hash to the same value as theutf-8body.
Example collision: Use UTF‑16 encoded bytes that decode to a different string but produce the same byte stream after the vulnerable hash function.
- Request A (legitimate user):
- Send Request B – the server returns the cached response from Request A (admin data), leaking it to the attacker.
Note: Actual collision strings depend on the hash implementation (e.g., Node.js crypto.createHash). The attacker can brute‑force body strings that produce the same hash while differing in charset interpretation.
Blue Team
Detection: Monitor for repeated POST requests to the same endpoint with different Content-Type charsets, especially if they originate from different IPs or user sessions. Enable detailed request logging.
Mitigation in lab:
- Update Next.js to a patched version (≥15.5.21 or ≥16.2.11).
- Temporarily block requests with non‑UTF‑8 charsets on sensitive endpoints.
- Deploy a reverse proxy (e.g., Nginx) to normalize
Content-Typecharset to UTF‑8.
Testing plan:
- Deploy a vulnerable Next.js instance (e.g., version 15.5.20).
- Create a
/api/secretroute that returns user‑specific data based on POST body. - Send two requests with different charsets and observe cache collision using debug logs.
- After patching, repeat the test – the cache should be separate.
Indicators of Compromise (IOCs)
Network traffic:
- POST requests with unusual
Content-Typecharset values:charset=utf-16,charset=utf-7,charset=iso-2022-jp, etc. - Multiple requests to the same URL with identical body size but different charset headers.
- HTTP responses that appear to contain data for a different user (e.g., mismatched session or content).
- POST requests with unusual
Application logs:
- Warnings about cache key collisions (if logging is enabled).
- Sudden increase in cache hit ratio for endpoints that normally receive varied request bodies.
File system (server):
No direct file IOCs; the cache resides in memory.
Detection Engineering
YARA Rule
rule Nextjs_CacheCollision_Request {
meta:
description = "Detects POST requests with non-UTF-8 charset targeting Next.js endpoints"
author = "Valters IT"
date = "2025-04-12"
hash = "somehash"
strings:
$s1 = "charset=utf-16" ascii nocase
$s2 = "charset=utf-7" ascii nocase
$s3 = "charset=iso-" ascii nocase
$s4 = "charset=windows-" ascii nocase
condition:
any of ($s*) and http_method == "POST"
}
Sigma Rule
title: Next.js Cache Collision via Non-UTF-8 Charset
id: 12345678-aaaa-4bbb-cccc-123456789abc
status: experimental
description: Detects HTTP POST requests with suspicious Content-Type charset values known to trigger CVE-2026-64647
logsource:
category: webserver
product: nextjs
detection:
selection:
http.method: POST
http.header|contains:
- 'charset=utf-16'
- 'charset=utf-7'
- 'charset=iso-2022'
- 'charset=windows-125' # any unusual charset
condition: selection
falsepositives:
- Legitimate use of non-UTF-8 charsets (rare in modern apps)
level: medium
Suricata Rule
alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"Next.js Cache Collision CVE-2026-64647 - Non-UTF-8 Charset in POST"; flow:to_server,established; http.method; content:"POST"; http.request_line; content:"Content-Type\:"; nocase; pcre:"/charset=(utf-16|utf-7|iso-2022|windows-125)/"; classtype:attempted-information-leak; sid:20260647; rev:1;)
Remediation & Mitigation
- Immediate: Upgrade Next.js to version 15.5.21 or 16.2.11 (or later).
- Workaround: If upgrading is not immediately possible, configure a reverse proxy (e.g., Nginx) to reject or normalize POST requests with non‑UTF‑8
Content-Typecharsets. - Long‑term: Enforce a security policy that all API endpoints using
fetchwith request bodies must validate the charset is UTF‑8. Add monitoring for abnormal header patterns. - Testing: Run cache regression tests after patch deployment to confirm no residual collisions.
Report generated by Valters IT – DevSecOps & Cyber Threat Intelligence Unit
Stay secure, stay patched.