GHSA-v3p8-whq6-r5jg: XSS

Published Sep 10, 2026
·
Updated

Summary An XSS vulnerability exists in @angular/platform-server during server-side rendering (SSR) HTML serialization when traversing ancestor tags across <template> element boundaries. When an application renders untrusted user input within raw-text tags (<xmp>, <style>, <script>), comments, or text nodes inside a <template> that is nested within a fallback raw-content element (<noscript>, <iframe>, <noembed>, <noframes>), matching closing tags (e.g., </noscript>) are not escaped during HTML serialization. When rendered in a browser, this unescaped closing tag prematurely terminates the fallback container and executes trailing markup as active DOM elements.

Technical Description In HTML5 parsing, fallback raw-content elements (<noscript>, <iframe>, <noembed>, <noframes>) place the browser's tokenizer into RAWTEXT mode. In this mode, inner content is parsed as literal text until an end tag matching the container tag name (e.g., </noscript>) is encountered.

To prevent XSS breakout vectors during SSR serialization, the DOM serializer inspects a node's ancestors to escape any matching fallback closing tags (</tag -> &lt;/tag). However: 1. Per DOM specifications, the children of a <template> element reside in a separate DocumentFragment (template.content), whose own parentNode is null. 2. The serializer's ancestor traversal previously only inspected element nodes. When traversing upward from a node inside template.content, traversal terminated immediately at the DocumentFragment boundary. 3. Because traversal stopped before reaching the outer document tree, enclosing fallback raw-content ancestors (such as <noscript> or <iframe>) were not discovered. As a result, closing sequences like </noscript> within <template> content were emitted unescaped.

Impact & Reachability Framework Guarantee Bypass: Angular guarantees that standard text interpolation ({{ userInput }} bound as element text content) is safe by default without manual sanitization. This vulnerability bypasses that guarantee during SSR HTML serialization when untrusted input is interpolated inside template content within fallback containers. Template Authoring: Writing literal <xmp> or <style> directly inside a component's <template> markup requires relaxed template schema checks (CUSTOMELEMENTSSCHEMA or NOERRORSSCHEMA). However, standard HTML comments and text nodes inside <template> within <noscript> are reachable without relaxed schemas. Imperative DOM Construction: Components or directives that construct DOM structures imperatively via Renderer2 bypass template compiler schema checks entirely and are unconditionally affected.

Proof of Concept (Minimal Reproduction) ts import { Component } from '@angular/core';

@Component({ selector: 'app-root', standalone: true, template: <noscript> <template> <xmp>{{ payload }}</xmp> </template> </noscript> }) export class AppComponent { // Attacker-controlled input bound via standard text interpolation payload = '</noscript><img src=x onerror=alert("SSRTEMPLATEXSS")>'; } Vulnerable SSR Output: html <noscript><template><xmp></noscript><img src=x onerror=alert("SSRTEMPLATEXSS")></xmp></template></noscript>

Workarounds Avoid rendering untrusted user input inside <template> elements nested within <noscript>, <iframe>, <noembed>, or <noframes> in server-rendered templates. Avoid programmatic DOM assembly of <template> elements inside fallback containers when handling untrusted data.

Affected Software

4 affected componentsFixes available
npm/@angular/platform-server<=19.2.25
npm/@angular/platform-server>=20.0.0<20.3.30
20.3.30
npm/@angular/platform-server>=21.0.0<21.2.22
21.2.22
npm/@angular/platform-server>=22.0.0<22.1.4
22.1.4

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade npm/@angular/platform-server to a version that resolves this vulnerability.

    Fixed in 20.3.30
  2. Upgrade

    Upgrade npm/@angular/platform-server to a version that resolves this vulnerability.

    Fixed in 21.2.22
  3. Upgrade

    Upgrade npm/@angular/platform-server to a version that resolves this vulnerability.

    Fixed in 22.1.4

Event History

Sep 10, 2026
Advisory Published
via GitHub·08:25 PM
Data Sourced
via GitHub·08:25 PM
DescriptionWeaknessAffected Software

Frequently Asked Questions

1

Which applications are exposed to this issue?

Applications using @angular/platform-server for SSR are exposed when they render untrusted input inside a <template> nested within a fallback raw-content element such as <noscript>, <iframe>, <noembed>, or <noframes>. The untrusted content must be placed in raw-text tags, comments, or text nodes.

2

What does an attacker need to provide to trigger the XSS breakout?

The attacker needs untrusted content to be rendered in the affected nested structure and to include a closing tag matching the surrounding fallback container, such as </noscript>. The serializer fails to escape that closing tag, allowing following markup to be parsed as active browser DOM.

3

Is every server-side rendered Angular page affected?

No. The described condition depends on a <template> boundary nested inside one of the specified fallback raw-content elements, together with untrusted content in the affected node types. The available information does not indicate impact outside that structure.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203