Introduction
undici is the HTTP/1.1 client that powers Node.js's built-in fetch(), and increasingly it's the networking layer underneath frameworks that advertise "zero-dependency" HTTP. When undici added request/response caching behavior to speed up repeated fetch() calls, it introduced a new trust boundary: cached entries now need to be scoped correctly, or a response fetched for one origin can leak into a request for a completely different origin.
That's the shape of CVE-2026-85152: an authentication bypass via cross-origin cache poisoning due to missing origin isolation. In plain terms, undici's cache implementation didn't key stored responses tightly enough by origin, so a cached entry populated by (or on behalf of) one origin could be returned for a request targeting another. If an application relies on origin boundaries to separate authenticated sessions — which almost every browser-adjacent or multi-tenant HTTP client does — this is exactly the kind of bug that turns a caching optimization into an authentication bypass.
This fix landed in this repository as a routine-looking dependency bump: undici moved from ^8.10.0 to ^8.10.2 in both package.json and the lockfile. No application code changed, because the vulnerable logic lives inside the undici package itself, not in first-party code.
Affected Versions
| Affected | undici releases up to and including 8.10.0 (any version prior to 8.10.2) |
| Fixed in | 8.10.2 |
| Ecosystem | npm |
| CVE / GHSA | CVE-2026-85152 / not assigned |
| CWE | unknown |
If your package.json or lockfile pins undici below 8.10.2, you are on a vulnerable release line. There is no GHSA advisory yet, and the upstream fix commit's internals aren't publicly detailed beyond the CVE summary, so treat the version boundary above as the authoritative signal.
The Vulnerability Explained
The advisory description is specific about the mechanism: a missing origin isolation in undici's response cache allowed cross-origin cache poisoning, which in turn enabled an authentication bypass. The practical failure mode is straightforward even without seeing undici's internal cache-key logic: a caching layer that stores and retrieves entries without binding them tightly to the requesting origin will, under the right request sequence, return origin A's cached response to a lookup made on behalf of origin B.
Why does that matter for authentication specifically? Any system that treats "this response came back for my origin" as an implicit trust signal — session cookies scoped to an origin, CSRF tokens tied to a Referer, or simply the assumption that a cached 200 response reflects this caller's authorized state — breaks the moment the cache can be poisoned cross-origin. An attacker who can get undici to cache a favorable response (for example, a successful authentication or authorization response) can then force or wait for a victim's request to hit that same cache entry, effectively bypassing whatever check should have happened on the live request path.
The PR that applied this fix is honest about its scope — it's a lockfile bump, not a code review of the exploit path:
- "undici": "^8.10.0",
+ "undici": "^8.10.2",
- "version": "8.10.0",
+ "version": "8.10.2",
That's the entire visible diff: a version range change in package.json and the resolved version in package-lock.json. The vulnerable logic — the cache key construction and lookup inside undici — isn't part of this repository's code, which is exactly why the fix is "upgrade the dependency" rather than "patch a function."
Attack scenario: any service using this project's undici-based fetch() calls to reach multiple origins (a proxy, an aggregator, a multi-tenant backend) is a candidate. If an attacker-controlled origin can get a response cached by undici's shared cache store, and a legitimate request to a different, trusted origin later resolves against that poisoned entry, the attacker's response — or the attacker's authentication state — can be returned instead of the real one. For a service whose name suggests it proxies requests on behalf of users (as the package.json here, serving a request-proxying project, does), this is a direct path from "cache bug" to "auth bypass."
The Fix
The fix is entirely a dependency upgrade: undici is bumped from 8.10.0 to 8.10.2 in both the dependency declaration and the lockfile.
Before:
"undici": "^8.10.0"
After:
"undici": "^8.10.2"
Because the vulnerable code lives inside the undici package, there's no first-party function to patch here — the correct remediation is simply to pull in the version where upstream maintainers corrected the cache key logic to enforce origin isolation. The lockfile change ensures npm install resolves the patched release deterministically rather than silently continuing to install 8.10.0 under the same ^8.10.0 range.
One caveat worth repeating from the PR itself: this fix was applied because undici appears in the dependency tree, without confirming that this application's code actually exercises undici's cache interceptor. If your usage of undici/fetch() never enables caching, your practical exposure may be lower — but since the fix is a no-risk patch bump with no API changes, there's little reason to delay applying it regardless.
Key Takeaways
- A caching layer is a second access-control surface — if it doesn't key strictly by origin, every assumption your authentication logic makes about "this is my response" can be violated.
undicipatch releases (8.10.0 → 8.10.2) can carry security fixes with no corresponding API change, so don't assume patch bumps are purely cosmetic.- When a dependency fix PR admits "I have not verified that your code reaches the affected function," that's a prompt to check whether your
fetch()usage actually enables undici's caching behavior — not a reason to skip the upgrade. - Lockfile-only diffs can carry high-severity fixes; reviewing
package.json/package-lock.jsonchanges with the same scrutiny as application code matters.
How Orbis AppSec Detected This
- Source: cross-origin HTTP requests handled through undici's
fetch()implementation and its response-caching layer - Sink: cache lookup/retrieval that returns a stored response without verifying it matches the requesting origin
- Missing control: origin isolation in the cache key, allowing a response cached for one origin to be returned for another
- CWE: unknown (not assigned in the source advisory)
- Fix: upgrade the
undicidependency from8.10.0to8.10.2, which