← Back to Feed CACHED · 2026-09-04 20:41:19 · CACHE_KEY CVE-2026-85008
CVE-2026-85008 · CWE-345 · Disclosed 2026-09-04

undici's cache interceptor documents that only safe HTTP methods are cached

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
Do you agree?
01 · The Real Story

A vending machine that keeps dispensing yesterday's sandwich because nobody told it POST means 'make a new one'

CVE-2026-85008 is a logic flaw in undici's cache interceptor — a feature consumers must explicitly opt into. The interceptor documents that only safe HTTP methods (GET, HEAD) are cached, but the skip-list was built by *subtracting* configured methods from the safe set rather than *allow-listing* them. The result: unsafe methods like POST, PUT, and DELETE fall through to the cache-read path, and the storage gate never checks the method either. If a remote origin returns a response with an explicit Cache-Control directive (or a heuristically cacheable status like 404 max-age=60), undici stores and replays it for subsequent requests to the same path — even state-changing ones. Affected versions are undici 7.0.0–7.29.0 and 8.0.0–8.10.1, fixed in 7.29.1 and 8.10.2.

The vendor rates this LOW / 3.7 and that assessment is accurate. The CVSS vector (AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N) reflects the reality: the attack only touches integrity (no data leak, no crash), requires the attacker to *be* or *compromise* the origin the client talks to, and only fires when the cache interceptor is enabled — which is not the default. Despite undici's enormous install base (~150M+ weekly npm downloads), the fraction of deployments that activate the cache interceptor is small, and the fraction where the origin is untrusted is smaller still.

"Opt-in cache feature with origin-side attack requirement keeps this firmly in backlog territory."
02 · The Attack Path

3 steps from start to impact.

STEP 01

Client enables cache interceptor

The Node.js application must import undici's cache interceptor and register it on the agent or pool. This is an opt-in API; default undici usage does not cache at all. Without this step, the entire chain is inert.
Conditions required:
  • Application code explicitly enables the cache interceptor
Where this breaks in practice:
  • Cache interceptor is not enabled by default — most undici consumers never touch it
  • Requires developer intent; no silent activation path
STEP 02

Malicious origin serves cacheable response to unsafe method

The attacker controls (or has compromised) the origin server the client speaks to. When the client issues a POST, PUT, or DELETE, the origin responds with a Cache-Control: max-age=3600 header or a heuristically cacheable status (e.g., 200, 404). Because the storage gate lacks a method check, undici stores this response.
Conditions required:
  • Attacker controls or has compromised the upstream origin
  • Client issues unsafe HTTP method to a path the attacker controls
Where this breaks in practice:
  • If the attacker already controls the origin, they have far more powerful attack options than cache poisoning
  • HTTPS/TLS prevents network-level MITM in standard deployments
STEP 03

Subsequent requests served from stale cache

When the client later issues another request to the same path (even a state-changing one), undici returns the cached response without forwarding to the origin. The client application acts on stale or attacker-crafted data, causing an integrity violation — e.g., a DELETE that silently returns a cached 200 instead of actually deleting a resource.
Conditions required:
  • Subsequent request to the same path occurs before cache TTL expires
Where this breaks in practice:
  • Impact is limited to integrity of responses within the single client process — no cross-user or cross-tenant leakage
  • Application-level validation or idempotency checks may catch stale responses
Detection/coverage: No scanner or EDR signature exists for this; detection would require application-level logging of cache hits vs. origin requests
03 · Intelligence Metadata

The supporting signals.

In-the-wild exploitationNone observed. No known campaigns, no CISA KEV listing, no vendor emergency advisory.
Proof-of-conceptNo public PoC exploit repository found. The advisory from MegaManSec (reporter) describes the logic flaw but no weaponized tooling.
EPSS scoreNot yet scored (CVE disclosed 2026-09-04, EPSS model lag expected). Given AC:H and I:L, expect bottom decile once scored.
KEV statusNot listed on CISA KEV as of 2026-09-05.
CVSS vectorCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N — network-reachable but high complexity, integrity-only impact, no scope change.
Affected versionsundici 7.0.0 – 7.29.0 and 8.0.0 – 8.10.1
Fixed versionsundici 7.29.1 and 8.10.2
Install base~150M+ weekly npm downloads (npmjs.com/package/undici). However, the cache interceptor is opt-in; exposed population is a small fraction of total installs.
Disclosure date2026-09-04
Reporter / creditsMegaManSec (reporter); mcollina and UlisesGascon (remediation)
04 · The Call

noisgate verdict.

Final Verdict
= UNCHANGED to LOW (3.7/10)

The single most decisive factor is that the cache interceptor is an opt-in feature disabled by default, which shrinks the reachable population to a small fraction of undici's install base. Combined with the requirement that the attacker must already control or compromise the upstream origin — a position that affords far more damaging attacks — the integrity-only, no-confidentiality, no-availability impact justifies LOW.

HIGH Vulnerability mechanics and affected versions
HIGH Severity assessment
MEDIUM Exposed population estimate (opt-in cache usage rate unknown)

Why this verdict

  • Opt-in feature gate: The cache interceptor is not enabled by default. Developers must explicitly register it. This alone eliminates the vast majority of undici's ~150M weekly download install base from the vulnerable population.
  • Attacker must own the origin: The CVSS vector requires AV:N/AC:H. In practice the attacker must control or compromise the upstream server the client talks to. At that point, cache poisoning is a strictly weaker attack than the alternatives already available (serving arbitrary malicious responses directly).
  • Integrity-only, single-process blast radius: Impact is limited to I:L — stale or crafted responses within one Node.js process. No confidentiality breach, no availability impact, no cross-user or cross-tenant leakage. The scope is Unchanged (S:U).
  • Role multiplier: undici is a user-space HTTP client library in Node.js. (a) *Low-value role*: dev scripts, CLI tools — no meaningful blast radius. (b) *Typical role*: backend microservice making outbound API calls — integrity issue confined to one service's view of upstream data. (c) *High-value role*: CI/CD build pipelines or internal proxies using undici with cache interceptor against semi-trusted registries — theoretically a supply-chain concern, but requires both opt-in caching AND compromised origin, making real-world occurrence vanishingly rare. No canonical high-value-role deployment (this is not a hypervisor, IdP, DC, or network edge). Floor does not apply.

Why not higher?

The attack requires the cache interceptor to be explicitly enabled (opt-in), the attacker to already control the origin server, and delivers only an integrity impact with no confidentiality or availability consequences. There is no public PoC, no KEV listing, no in-the-wild exploitation, and no cross-boundary scope change. Elevating to MEDIUM would require at least one of: default-on exposure, broader impact category, or evidence of exploitation.

Why not lower?

The flaw is real and affects a widely-used library. While opt-in, the cache interceptor exists for a reason and some production deployments do use it. The integrity violation — silently serving stale responses to state-changing requests — can cause subtle, hard-to-diagnose application logic errors. IGNORE would understate the risk for the subset of applications that have opted in.

05 · Compensating Control

What to do — in priority order.

  1. Audit your codebase for cache interceptor usage — Search for CacheInterceptor, interceptors.cache, or cacheInterceptor in your Node.js projects. If none are found, this CVE does not affect you. Complete this audit within your normal backlog cycle.
  2. Upgrade undici to 7.29.1 or 8.10.2 — The fix adds a method check to both the cache-read and cache-write gates. For a LOW verdict there is no noisgate mitigation SLA — treat this as backlog hygiene and roll the upgrade into your next scheduled dependency update.
  3. Pin unsafe-method paths to no-cache if upgrading is delayed — If you cannot upgrade immediately, configure the cache interceptor's methods option to explicitly list only GET and HEAD, or add Cache-Control: no-store headers to outbound unsafe-method requests at the application layer.
What doesn't work
  • WAF / reverse proxy caching rules — This is a client-side cache bug, not a server-side cache poisoning issue. Your edge infrastructure has no visibility into undici's in-process cache.
  • Network-level controls (firewall, IDS) — The cached responses travel over normal HTTPS connections; there is no network signature to detect or block.
06 · Verification

Crowdsourced verification payload.

Run this on any host where your Node.js applications are deployed, or in your CI pipeline. Requires node (v18+) and read access to node_modules. Example: bash check_cve_2026_85008.sh /app

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# check_cve_2026_85008.sh — Detect undici versions vulnerable to CVE-2026-85008
# Usage: bash check_cve_2026_85008.sh [PROJECT_DIR]
# Exit codes: 0 = PATCHED/NOT_AFFECTED, 1 = VULNERABLE, 2 = UNKNOWN

set -euo pipefail

PROJECT_DIR="${1:-.}"

if [ ! -d "$PROJECT_DIR" ]; then
  echo "UNKNOWN — directory $PROJECT_DIR does not exist"
  exit 2
fi

# Find all undici installations
found=0
vulnerable=0

while IFS= read -r pkg_json; do
  version=$(node -e "try{console.log(require('$pkg_json').version)}catch(e){console.log('error')}" 2>/dev/null)
  if [ "$version" = "error" ] || [ -z "$version" ]; then
    continue
  fi
  found=1
  # Parse major.minor.patch
  IFS='.' read -r major minor patch <<< "$version"
  # Vulnerable: 7.0.0-7.29.0 or 8.0.0-8.10.1
  if [ "$major" -eq 7 ]; then
    if [ "$minor" -lt 29 ] || ([ "$minor" -eq 29 ] && [ "$patch" -lt 1 ]); then
      echo "VULNERABLE — undici $version found at $pkg_json (fix: 7.29.1)"
      vulnerable=1
    else
      echo "PATCHED — undici $version at $pkg_json"
    fi
  elif [ "$major" -eq 8 ]; then
    if [ "$minor" -lt 10 ] || ([ "$minor" -eq 10 ] && [ "$patch" -lt 2 ]); then
      echo "VULNERABLE — undici $version found at $pkg_json (fix: 8.10.2)"
      vulnerable=1
    else
      echo "PATCHED — undici $version at $pkg_json"
    fi
  else
    echo "PATCHED — undici $version at $pkg_json (outside affected range)"
  fi
done < <(find "$PROJECT_DIR" -path '*/undici/package.json' -not -path '*/node_modules/.cache/*' 2>/dev/null)

if [ "$found" -eq 0 ]; then
  echo "UNKNOWN — no undici installations found in $PROJECT_DIR"
  exit 2
fi

if [ "$vulnerable" -eq 1 ]; then
  exit 1
else
  exit 0
fi
07 · Bottom Line

If you remember one thing.

TL;DR
This is a LOW-severity backlog item. The cache interceptor is opt-in and disabled by default, the attacker must already own the origin, and impact is limited to response integrity within a single process. Per the noisgate remediation SLA for LOW, there is no mitigation deadline — treat this as backlog hygiene. First, audit whether any of your Node.js services actually enable the undici cache interceptor; if none do, document and close. If you do use it, roll the upgrade to undici 7.29.1 or 8.10.2 into your next scheduled dependency refresh. No emergency patching, no weekend work — just make sure it lands before your next quarterly dependency sweep.

Sources

  1. GitHub Security Advisory GHSA-8436-99hf-9mmv
  2. CVE-2026-85008 — THREATINT
  3. undici on npm
  4. undici releases — GitHub
  5. undici security advisories — GitHub
  6. CVE-2026-85008 — TheHackerWire
  7. FIRST EPSS FAQ
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.