CVE-2026-69149, CVE-2026-68945 and CVE-2026-69151: Angular SSR XSS, Transfer Cache Poisoning, and i18n XSS
How unescaped SSR serialization, ambiguous transfer-cache keys, and translatable event-handler attributes let attackers inject script and poison server-rendered responses across three related Angular vulnerabilities
.png)
On July 29, 2026, the Angular team published three High-severity security advisories affecting Angular's server-side rendering (SSR) and internationalization (i18n) pipelines. CVE-2026-69149 (GHSA-vpx6-8pjr-4g3v) is a Cross-Site Scripting flaw (CWE-79) in @angular/platform-server's DOM serialization, scored 8.6. CVE-2026-68945 (GHSA-jhpw-976m-542j) is a cache-key ambiguity (CWE-345) in @angular/common's HttpTransferCache, scored 8.8. CVE-2026-69151 (GHSA-jj27-h5hq-8x99) is a second XSS (CWE-79) in the Angular compiler's i18n pipeline, scored 7.6.
All three affect every Angular version line through 22.x. Angular 22, 21, and 20 received patches in 22.0.7 (and 22.0.2 / 22.0.1 for the respective packages), 21.2.19, and 20.3.27. Angular 19 and earlier are end of life with no OSS fix available.
Affected and unsupported? See NES for Angular.
What are these vulnerabilities?
The three advisories were disclosed as a batch, share the same affected version ranges, and are fixed by the same patch-level updates. But they are mechanically distinct bugs in three different packages.
CVE-2026-69149: XSS via unescaped fallback raw-content serialization in Angular SSR
@angular/platform-server renders Angular applications on the server using domino, a DOM emulation library. When a template binds dynamic text inside fallback raw-content elements (<iframe>, <noembed>, <noframes>, <noscript>), domino's serializer did not escape text nodes within those elements during DOM serialization. A closing tag inside bound user-controlled data therefore survives serialization intact. When the browser (or the SSR post-processing step itself) re-parses that output, the injected closing tag terminates the raw-content element early, and whatever follows, including an injected <script> block, executes in the application's origin. This is a classic CWE-79 Cross-Site Scripting flaw, delivered through a serializer gap rather than a template-sanitization gap.
CVE-2026-68945: Cache-key ambiguity in HttpTransferCache
Angular's HttpTransferCache (in @angular/common) caches HTTP responses fetched during SSR so client-side hydration can reuse them instead of refetching. The cache key was built by joining repeated query parameter values with commas. That means new HttpParams().set('role', 'user,admin') and new HttpParams().append('role', 'user').append('role', 'admin') both serialize to role=user,admin and collide on the same cache key. Two semantically different requests become one cache entry. The advisory classifies this as CWE-345, Insufficient Verification of Data Authenticity: the framework trusts a cached response that was never verified to belong to the request consuming it.
CVE-2026-69151: XSS via event-handler attributes in Angular i18n
Angular's attribute validation (validateAttribute() / validateProperty()) blocks binding to event-handler attributes like onclick and onerror. But the compiler's i18n metadata collection path allowed those same attribute names to be marked for translation via i18n-on* attributes, for example <img src="foo.jpg" onerror="void 0" i18n-onerror />. A lower-trust translation file can then replace the benign static handler with arbitrary JavaScript in the localized build. This is CWE-79 again, but the injection vector is the localization supply chain rather than runtime user input.
Severity and exploit conditions
All three scores below are CVSS v4, assigned by the Angular team in the GitHub advisories. None of the three requires authentication (PR:N across the board), and all are network-exploitable.
CVE-2026-69149: 8.6 High (CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N)
Exploit precondition: the application binds user-controlled data inside a fallback raw-content element on an SSR-rendered page.
CVE-2026-68945: 8.8 High (CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:L/VA:N/SC:N/SI:N/SA:N)
Exploit precondition: an SSR application makes repeated-parameter requests to an endpoint where an attacker can influence a colliding scalar-comma request in the same render.
CVE-2026-69151: 7.6 High (CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N)
Exploit precondition: a template marks a static event-handler attribute for translation with i18n-on*, and the attacker can influence the translation files used at build time.
What an attacker can do
Hijack sessions on SSR pages (CVE-2026-69149). Any SSR-rendered page that binds user-controlled data inside <iframe>, <noembed>, <noframes>, or <noscript> can be turned into a same-origin XSS delivery point. An injected closing tag breaks out of the raw-content element and executes attacker script against every visitor, enabling session hijacking, credential theft, actions performed as the victim, and defacement.
Serve the wrong backend response to a trusted request (CVE-2026-68945). An attacker-influenced request using a comma-joined scalar value (role=user,admin) can be cached, then replayed as the response to a later, semantically different repeated-parameter request in the same render, for example a trusted authorization or data lookup to the same URL. The trusted request is never dispatched. Angular's server-rendered output is then built on an attacker-influenced state which could include state poisoning and cross-request response reuse.
Turn a translation file into an execution vector (CVE-2026-69151). A compromised or lower-trust translation source can replace a harmless static handler like onerror="void 0" with arbitrary JavaScript that ships in the localized production build. Every user of that locale runs the payload, with the same session-hijacking and account-takeover consequences as any stored XSS.
Who is affected?
The affected version ranges are effectively identical across all three advisories. The affected packages are @angular/platform-server (CVE-2026-69149), @angular/common (CVE-2026-68945), and @angular/compiler with @angular/core (CVE-2026-69151).
Angular 19 reached end of life on May 19, 2026, and the v19-lts npm dist-tag remains frozen at 19.2.25, the last release and one that is affected by all three advisories. Every earlier Angular line (18, 17, 16, and back through the AngularJS boundary) has been EOL longer and is equally unpatched. If your application runs Angular 19 or anything older, these three advisories join a growing list of vulnerabilities that upstream will never fix for your version.
Mitigation guidance
Updating to a patched release resolves all three vulnerabilities at once.
The workarounds are real but narrow. Disabling critical CSS inlining changes rendering performance characteristics, disabling the transfer cache reintroduces duplicate fetches during hydration, and template audits only help if they are exhaustive. Treat them as bridges to a patched version, not destinations.
Related CVEs
This batch extends a sustained run of Angular security activity in 2026, much of it concentrated in the same two subsystems.
The i18n pipeline has now produced three XSS advisories this year - today's i18n-on* flaw follows CVE-2026-27970, an XSS in Angular i18n ICU message handling, and CVE-2026-32635, an XSS through i18n attribute bindings. The pattern across all three is the same - the i18n metadata path trusts translated content in places the standard sanitization path never would.
On the SSR side, @angular/platform-server has had a string of 2026 advisories, including CVE-2026-27739, SSRF and header injection in the SSR request handling pipeline and CVE-2026-50168, an SSRF allowlist bypass via a URL parser differential. For the broader picture of how fast this advisory stream is moving, see Angular's 2026 CVE surge: 21 new advisories, no patches for EOL apps.
Taking action
If you are on Angular 20, 21, or 22, this is a straightforward patch cycle - update to 20.3.27, 21.2.19, or the current 22.x release and all three advisories are resolved together. Do it soon. The SSR serialization flaw in particular has a low exploitation bar on any page that reflects user input.
If you are on Angular 19 or earlier, the calculus is different. These three High-severity vulnerabilities will never receive an upstream fix for your version, and they arrive on top of the year's earlier unpatched advisories for EOL lines. Your options are a major-version migration on the attacker's timeline, or staying secure on the version you have. NES for Angular delivers drop-in replacement builds that remediate vulnerabilities like these across EOL Angular versions, so you can migrate on your schedule instead.
Resources
View All Articles
.png)

