CVE-2026-68945: @angular/common HttpTransferCache Cache-Key Ambiguity Leads to State Poisoning
Angular's server-side rendering cache treats two structurally different HTTP requests as identical, letting an attacker-controlled response be silently served in place of a legitimate one during…

The problem
Angular's HttpTransferCache stores SSR responses so the browser can reuse them during hydration instead of re-fetching. When building the cache key, repeated multi-value parameters were joined with commas, the same character a scalar string value can contain.
This means role=user,admin (one param, one string value) and role=user&role=admin (one param, two values) produced the same key material. Any two requests that share a URL but differ only in how they pass a repeated parameter were treated as the same request, so whichever ran first wins and the second never reaches the backend.
Proof of concept
A working proof-of-concept for CVE-2026-68945 in @angular/common, with the exact payload below.
// Two distinct Angular HttpClient calls that collide to the same transfer-cache key
// Call 1 - scalar comma value (attacker-influenced, runs first during SSR)
this.http.get('/api/resource', {
params: new HttpParams().set('role', 'user,admin')
});
// Call 2 - trusted multi-value request (runs second, hits the poisoned cache entry)
this.http.get('/api/resource', {
params: new HttpParams().append('role', 'user').append('role', 'admin')
});
// Both serialise to the key material: role=user,admin
// Call 2 never reaches the backend; it receives Call 1's cached response.The bug lives in the cache-key construction step inside HttpTransferCache. Before the fix, multi-value params were collapsed with .join(','), so ['user','admin'] became the string user,admin, which is byte-identical to the scalar value user,admin. The patch changes how repeated keys are serialised into the key string so that role=user&role=admin and role=user,admin produce distinct key material, making the ambiguity structurally impossible.
CWE-345 (Insufficient Verification of Data Authenticity) applies because the cache never verified that a stored entry actually corresponded to the semantics of the incoming request.
The fix
Upgrade to @angular/common 22.0.2 (or 21.2.19 / 20.3.27 for older trains). If an immediate upgrade is not possible, set transferCache: false on any sensitive request, or disable the transfer cache globally with provideClientHydration(withNoHttpTransferCache()).
Related research
- high · 7.7CVE-2026-50132: Budibase Chat-Link Handoff Identity Confusion CSRF
- high · 8.3better-auth Pre-Account Hijacking via Magic-Link and Email-OTP Sign-In
- highn8n: Account Takeover via Unverified Email Claim in Embed Login Token Exchange
- high · 7.7CVE-2026-53514CVE-2026-53514: better-auth Organization Invitation Takeover via Unverified Email Pre-Registration