Angular @angular/platform-server SSR escaping flaw enables cross-site scripting

Note: This data is for reference and cybersecurity research purposes only.CyStack advises users not to use this information for unlawful purposes.

What is CVE-2026-88058?

CVE-2026-88058 is a vulnerability classified as Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') and Improper Encoding or Escaping of Output, affecting angular (affected versions: <= 19.2.25, >= 20.0.0, < 20.3.30, and other affected versions). This vulnerability is rated High, with a CVSS score of 8.6. Public exploit code or evidence is available for this vulnerability, but that does not confirm exploitation in the wild.

Overview

Original source data

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 products and scope

  • @angular/platform-server in the <= 19.2.25 branch is affected. The advisory states that this branch is end of support or LTS expired and will not be patched.
  • Versions >= 20.0.0, < 20.3.30 are affected; the corresponding fixed release is 20.3.30.
  • Versions >= 21.0.0, < 21.2.22 are affected; the corresponding fixed release is 21.2.22.
  • Versions >= 22.0.0, < 22.1.4 are affected; the corresponding fixed release is 22.1.4.
  • Do not infer safety for other branches or packaging arrangements that are not covered by the confirmed affected ranges.

Technical details

Angular @angular/platform-server performs server-side rendering through HTML serialization logic associated with its bundled domino dependency. For ProcessingInstruction nodes, the affected serializer escaped > in the data but left < unchanged and did not invoke fallback-ancestor handling such as fallbackRawContentTags(). In HTML5, noscript, iframe, noembed, and noframes elements place the tokenizer in RAWTEXT mode; when the data contains a matching closing-tag sequence, the tokenizer can terminate the container early and interpret subsequent sibling elements as active HTML. Reaching this path requires application or library code to create or insert a ProcessingInstruction node with attacker-controlled data, for example through inject(DOCUMENT).createProcessingInstruction(...), inside a fallback container rendered by SSR. Standard Angular templates do not create this node because the corresponding syntax is parsed as a comment node, making the exposure narrower than ordinary SSR XSS paths. The affected application's route, input source, and data flow to the node remain application-specific.

Exploitability

The vulnerability is reachable over the network through an Angular application using SSR. The supplied assessment describes exploitation as requiring no special privileges, having low complexity, and requiring passive victim interaction, meaning the victim must load or render an affected SSR response. The attacker must still reach a code path that places attacker-controlled data in a ProcessingInstruction node inside a fallback raw-content element; standard Angular templates do not provide that path. The record marks a public exploit as available, and the advisory contains a minimal reproduction, but it does not identify a named campaign or confirm exploitation in the wild. The known-exploited field does not establish evidence of an in-the-wild campaign.

Technical impact

When the reachability conditions are met, the serializer can emit HTML in which a fallback container is closed early by processing-instruction data. Sibling elements that were expected to remain fallback content are no longer confined to raw text and can become active browser markup. The technical outcome is arbitrary JavaScript execution in the victim's browser, with potential access to data and actions available to that context. The flaw does not by itself demonstrate server-side code execution, service disruption, or exposure of every Angular application because creation of the node and attacker control of its data are required.

Business impact

In an affected SSR application, attacker-controlled input can change how the browser interprets returned HTML and trigger JavaScript in the victim's page context. Depending on the data exposed by the application and the victim's permissions, that script could read accessible page data, alter the interface, or perform actions as the victim. The practical impact is constrained by the narrow reachability condition: the application must create a processing instruction with untrusted data inside a fallback raw-content element. The record supports confidentiality and integrity consequences in the browser, but does not establish server compromise or a service-availability impact.

Remediation

  1. Upgrade @angular/platform-server to the fixed release for the deployed branch: use 20.3.30 for branch 20, 21.2.22 for branch 21, or 22.1.4 for branch 22. Verify that the deployed SSR artifact actually uses the remediated dependency.
  2. For deployments in the <= 19.2.25 branch, move to a supported Angular branch and apply its corresponding fixed release because the advisory states that the end-of-support branch will not be patched.
  3. If an immediate upgrade is not possible, do not pass untrusted input to document.createProcessingInstruction(target, data) when the node is inserted into noscript, iframe, noembed, or noframes during SSR.
  4. Apply the server-side workaround described by the advisory: sanitize untrusted data or replace < with &lt; before passing it to a processing-instruction node. This is a temporary control, not a substitute for upgrading.
  5. After upgrading, retest processing-instruction creation paths, especially paths using the domino dependency, and verify that matching ancestor closing tags are escaped in SSR HTML.

Detection

  1. Inventory Angular SSR applications and services, checking dependency trees, lockfiles, and runtime artifacts for @angular/platform-server.
  2. Search source code for inject(DOCUMENT).createProcessingInstruction, createProcessingInstruction, and DOM insertion flows using Renderer2, then determine whether untrusted input can reach the data field.
  3. Review code paths that create nodes inside or below noscript, iframe, noembed, and noframes during SSR.
  4. Inspect generated SSR HTML for matching fallback-container closing tags appearing unescaped inside processing-instruction data.
  5. Run a regression test against SSR output with a processing instruction containing representative closing-tag data for each fallback container, and verify that the container cannot be terminated early and sibling markup remains inert.
  6. CSP violation reports, browser telemetry, and unexpected changes in SSR HTML can be reviewed as additional monitoring precautions. These are not confirmed indicators, and the absence of log evidence does not prove that a deployment is safe.
Sources (20)
Learn more

Run an in-depth assessment with complete web risk management

CyStack VulnScan continuously discovers assets, validates vulnerabilities, and helps security teams prioritize remediation across the organization.