Packages / @angular/platform-server / Security
@angular/platform-server: Missing `<noscript>` Raw-Text Serialization Escaping leads to Cross-Site Scripting (XSS) in Angular SSR
Affected releases · @angular/platform-server
- 21.x21.0.0 – 21.2.15Fixed in 21.2.16
- 20.x20.0.0 – 20.3.23Fixed in 20.3.24
- 19.x19.0.0 – 19.2.24Fixed in 19.2.25
- 18.x and older2.0.0 – 18.2.14No fix, no longer updated
On 21.x, the newest line:
npm install @angular/platform-server@21.2.16Not affected
22.0.0 – 22.2.3
22 releases, latest
Affected
21.0.0 – 21.2.15
33 releases
Fixed
21.2.16 – 21.2.25
10 releases
Affected
20.0.0 – 20.3.23
45 releases
Fixed
20.3.24 – 20.3.34
11 releases
Affected
19.0.0 – 19.2.24
42 releases
Fixed
19.2.25
1 release
Affected
18.0.0 – 18.2.14
29 releases
Affected
17.0.0 – 17.3.12
32 releases
Affected
16.0.0 – 16.2.12
30 releases
Affected
15.0.0 – 15.2.10
22 releases
Affected
14.0.0 – 14.3.0
26 releases
Affected
13.0.0 – 13.4.0
30 releases
Affected
12.0.0 – 12.2.17
30 releases
Affected
11.0.0 – 11.2.14
28 releases
Affected
10.0.0 – 10.2.5
28 releases
Affected
9.0.0 – 9.1.13
22 releases
Affected
8.0.0 – 8.2.14
23 releases
Affected
7.0.0 – 7.2.16
27 releases
Affected
6.0.0 – 6.1.10
20 releases
Affected
5.0.0 – 5.2.11
22 releases
Affected
4.0.0 – 4.4.7
29 releases
Affected
2.0.0 – 2.4.10
24 releases
Is your project affected?
Paste your package.json, or type the range you declare for @angular/platform-server. It is read in your browser and sent nowhere.
What happens
A Cross-Site Scripting (XSS) vulnerability exists in @angular/platform-server's DOM emulation dependency (domino) when serializing the content of <noscript> elements.
When rendering dynamic text content inside a <noscript> element via template bindings (such as {{ value }} or [textContent]), the template engine expects the browser to render the content safely. Under Server-Side Rendering (SSR), domino is configured with scripting enabled, meaning <noscript> is treated as a raw-text element.
However, domino's serializer completely omitted <noscript> from the list of raw-text elements requiring closing-tag escaping during DOM serialization. As a result, any occurrence of </noscript> in the bound dynamic text was never escaped under any circumstances.
The unescaped closing tag was serialized directly into the output HTML (e.g. <noscript></noscript><script>alert(1)</script></noscript>). When parsed by a browser, it closes the <noscript> block early, allowing the injected <script> block to execute in the user's browser context, causing same-origin Cross-Site Scripting (XSS).
Impact
This vulnerability allows an attacker to perform same-origin Cross-Site Scripting (XSS) attacks against any user visiting an SSR-rendered page that binds user-controlled data inside a <noscript> element. This can lead to session hijacking, credentials theft, unauthorized actions on behalf of users, and defacement.
Patched Versions
22.0.0-rc.2
21.2.16
20.3.24
19.2.25
Workarounds
If you cannot immediately update your dependencies, you can:
Avoid binding user-controlled values inside
<noscript>elements.Sanitize any user input placed inside
<noscript>to explicitly strip closing</noscript>tags before passing it to the template.