CVE-2026-88058
Medium · 6.1CVSS
6.1
EPSS
0.3%
Published
Sep 10, 2026
CISA due date
—
Cloudanix analysis
A flaw in how Angular builds web pages on the server can let an attacker run their own code in a visitor’s browser if the app inserts certain untrusted special content into the page.
- Exploitation
- Requires User Interaction
- Attacker needs
- None
- Complexity
- Moderate
- Impact
- Data Exposure
- Component
- Web Framework
- Class
- XSS
- Remediation
- Upgrade
- Effort
- Low
- Patch risk
- Low
What it actually does
Angular server-side rendering in @angular/platform-server incorrectly serializes ProcessingInstruction DOM nodes placed inside HTML5 RAWTEXT fallback containers (noscript, iframe, noembed, noframes). Greater-than characters in ProcessingInstruction data were escaped, but less-than characters were left intact and ancestor closing tags were not inspected, so a matching closer can terminate the container early. Subsequent sibling markup is then parsed as live HTML rather than raw text, which can execute arbitrary JavaScript in the victim browser. The issue is not reachable via normal Angular templates; it requires application or library code that creates ProcessingInstruction nodes with untrusted data (for example via inject(DOCUMENT).createProcessingInstruction) or Renderer2 insertion inside a fallback container.
Why it matters to the business
If an Angular SSR application takes this non-standard DOM path with attacker-influenced data, a visiting user can have malicious script run in their session, leading to account takeover, session theft, or data theft from the rendered origin. Exploit code is already publicly available even though this CVE is not in CISA KEV, so exposure should be treated as time-sensitive rather than theoretical. Impact is limited to apps that use SSR and custom ProcessingInstruction or Renderer2 insertion inside RAWTEXT elements, but those that do so face a client-side integrity failure on pages users are expected to trust. Patch within the current maintenance cycle; the issue has been public for several weeks.
How an attack unfolds
An attacker first finds an Angular SSR application or dependent library that programmatically creates a ProcessingInstruction (or inserts equivalent DOM via Renderer2) inside a noscript, iframe, noembed, or noframes container, using data the attacker can influence. They supply content that includes a less-than sequence matching the ancestor RAWTEXT closing tag. During SSR, Angular serializes that node without escaping the less-than or checking fallback ancestors, so the HTML5 parser treats the container as closed. Markup the attacker placed after that point is interpreted as live HTML in the victim’s browser when the rendered page is viewed, executing script in the application origin. Standard template binding does not create the vulnerable nodes, so exploitation depends on that custom DOM path plus a user visiting the SSR response.
How to fix it
Upgrade @angular/platform-server (and the matching Angular release line) to 20.3.30, 21.2.22, or 22.1.4 or later. Prefer the latest patched release on your supported major. After upgrading, rebuild and redeploy SSR bundles so stale server renderers are not left in production. Until patched, avoid creating ProcessingInstruction nodes with untrusted data and do not insert attacker-controlled DOM via Renderer2 or inject(DOCUMENT) inside noscript, iframe, noembed, or noframes. Review application and third-party library code for createProcessingInstruction and Renderer2 usage in fallback containers. Do not treat CSP or output encoding of ordinary template bindings as a complete substitute for the framework upgrade.
How to confirm the fix worked
Confirm package versions of @angular/core and @angular/platform-server resolve to 20.3.30+, 21.2.22+, or 22.1.4+ in lockfiles and in the built SSR server image. Search application and dependency source for inject(DOCUMENT).createProcessingInstruction, document.createProcessingInstruction, and Renderer2 create/insert calls that target RAWTEXT containers. After upgrade, render representative SSR pages that historically included processing instructions or fallback content and verify serialized HTML no longer emits an unescaped ancestor closer inside those containers. Regression-test SSR output in a browser or HTML5 parser and confirm sibling content remains inert text rather than live DOM. Re-scan production artifacts, not only source, because stale SSR bundles can remain after a library bump.
Typical attack path
- Identify an Angular SSR app or library that creates ProcessingInstruction nodes or uses Renderer2 insertion inside a noscript, iframe, noembed, or noframes container with attacker-influenced data.
- Submit input that includes a less-than sequence matching the enclosing RAWTEXT closing tag.
- Trigger server-side rendering so the unsafe serialization is written into the HTML response.
- Lure a victim to load the rendered page (link, redirect, or normal app navigation).
- The premature container close causes following markup to parse as live HTML, running attacker JavaScript in the victim’s browser origin.
How to detect it
Hunt for whether this was already abused by inspecting SSR HTML responses and CDN/cache copies of Angular-rendered pages for ProcessingInstruction markup (<? ... ?>) inside noscript, iframe, noembed, or noframes, especially where a matching closing tag appears in that data and following siblings look like live HTML rather than raw text. Review web and WAF logs around the publication window for requests that submitted angle-bracket sequences into fields later reflected through SSR. Check Content-Security-Policy violation reports and browser telemetry for unexpected inline or foreign-origin script on SSR routes. On hosts that run the Node SSR process, search application logs and error traces for createProcessingInstruction and Renderer2 insertion into fallback containers. Compare cached pre-patch HTML snapshots to post-patch output for the same routes. There are no named threat actors or KEV ransomware associations for this CVE, so detections should focus on the SSR HTML artifact and the custom DOM API path rather than a specific malware family.
- createProcessingInstruction
- inject(DOCUMENT)
- <?
- </noscript>
- </iframe>
- </noembed>
- </noframes>
- @angular/platform-server
What your security team should do
- Patch Angular SSR to 20.3.30, 21.2.22, or 22.1.4 immediately; exploit code is already available.
- Inventory apps using @angular/platform-server and flag those that call createProcessingInstruction or Renderer2 inside noscript, iframe, noembed, or noframes.
- Rebuild and redeploy SSR servers so old renderer code cannot remain in production images.
- Review third-party Angular libraries for the same DOM insertion pattern, not only first-party templates.
- Enforce a strict Content-Security-Policy as defense in depth, but do not delay the framework upgrade.
- Add a CI check that fails builds still resolving vulnerable @angular/platform-server versions.
The record
Angular is a development platform for building mobile and desktop web applications using TypeScript/JavaScript and other languages. Prior to 20.3.30, 21.2.22, and 22.1.4, Angular server-side rendering (SSR) in @angular/platform-server serializes ProcessingInstruction DOM nodes inside fallback raw-content elements without escaping matching ancestor closing tags. ProcessingInstruction data escaped greater-than characters but left less-than characters untouched and did not inspect fallback ancestors, so data such as a matching closing tag prematurely terminates noscript, iframe, noembed, or noframes containers. The vulnerable nodes cannot be authored through standard Angular templates; reachability requires application or library code using inject(DOCUMENT).createProcessingInstruction with attacker-controlled data or Renderer2 DOM insertion inside a fallback container. In HTML5 RAWTEXT parsing, the premature close causes subsequent sibling elements to be interpreted as live HTML and enables arbitrary JavaScript execution in a victim's browser. This issue is fixed in versions 20.3.30, 21.2.22, and 22.1.4.
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|
Related vulnerabilities
- CVE-2026-96379 Improper Neutralization of Input During Web Page Generation ("Cross-site Scripting")… CWE-79
- CVE-2026-96382 Improper Neutralization of Input During Web Page Generation ("Cross-site Scripting")… CWE-79
- CVE-2026-96368 Improper Neutralization of Input During Web Page Generation ("Cross-site Scripting")… CWE-79
- CVE-2026-96361 Improper Neutralization of Input During Web Page Generation ("Cross-site Scripting")… CWE-79
- CVE-2026-96362 Improper Neutralization of Input During Web Page Generation ("Cross-site Scripting")… CWE-79
- CVE-2026-96360 Improper Neutralization of Input During Web Page Generation ("Cross-site Scripting")… CWE-79
- CVE-2026-96357 Improper Neutralization of Input During Web Page Generation ("Cross-site Scripting")… CWE-79
- CVE-2026-96358 Improper Neutralization of Input During Web Page Generation ("Cross-site Scripting")… CWE-79