Mar 14, 2026·6 min read·4 visits
Angular's i18n attribute parsing bypasses sanitization, allowing arbitrary XSS execution via data-bound sensitive attributes like `href` or `src`.
Angular framework versions 17.x through 22.0.0-next.2 contain a cross-site scripting (XSS) vulnerability due to an improper sanitization bypass in the internationalization (i18n) compiler pipeline. When sensitive HTML attributes like `href` or `src` are marked for translation using the `i18n-` prefix, the Angular Ivy renderer fails to apply default security sanitization to their bound values. This permits the injection of malicious `javascript:` URIs.
CVE-2026-32635 is a Cross-Site Scripting (XSS) vulnerability located within the Angular framework's internationalization (i18n) and template compilation subsystems. The flaw manifests when developers utilize Angular's i18n tagging feature on security-sensitive DOM attributes. Specifically, prepending the i18n- directive to attributes such as href or src causes the Angular Ivy renderer to process the attribute bindings through a distinct compilation path.
This distinct compilation path omits the framework's built-in URI sanitization routines. Angular typically inspects dynamic property bindings to ensure they do not contain dangerous protocol handlers like javascript: or vbscript:. The i18n parsing logic entirely circumvents this inspection step, trusting the bound value without validation.
Consequently, applications dynamically binding untrusted user data to translated sensitive attributes are exposed to arbitrary JavaScript execution in the client browser. An attacker providing a malicious payload can achieve full execution context within the victim's session. The vulnerability affects multiple major releases, spanning from Angular 17.x to the 22.0.0 next-release candidates.
The root cause of CVE-2026-32635 resides in the Angular Ivy (Render3) compiler's processing instructions for i18n-marked attributes. When the compiler encounters a standard dynamic binding on a sensitive attribute (e.g., [href]="userUrl"), it emits specific operational codes (OpCodes) that mandate runtime sanitization. This ensures the bound value passes through functions like _sanitizeUrl before DOM insertion.
When the i18n- prefix is introduced, the compiler delegates processing to the i18nAttributesFirstPass function located within packages/core/src/render3/i18n/i18n_parse.ts. This function is responsible for generating the update instructions for translated attributes. During this generation phase, the function explicitly passes a null value for the sanitizer argument, regardless of the target attribute's inherent risk profile.
Passing null instructs the runtime environment to execute a direct property write without any preceding validation or transformation. The framework loses the ability to distinguish between benign HTTP URLs and dangerous script execution URIs. This omission effectively disables the primary XSS defense mechanism for specifically targeted template components.
An examination of the Angular core repository reveals the exact location of the security bypass in the i18n parsing pipeline. The generateBindingUpdateOpCodes function handles the orchestration of binding updates for translated attributes. Prior to the patch, the function call explicitly hardcoded the sanitizer parameter to null.
// packages/core/src/render3/i18n/i18n_parse.ts (Vulnerable)
export function i18nAttributesFirstPass(...) {
// ...
generateBindingUpdateOpCodes(
updateOpCodes,
previousElementIndex,
attrName,
countBindings(updateOpCodes),
null, // <--- Sanitizer explicitly set to null
);
// ...
}The remediation requires the compiler to dynamically determine the appropriate sanitization function based on the attribute name. The patch modifies packages/core/src/render3/i18n/i18n_parse.ts to query the internal URI_ATTRS map. If the target attribute requires URL sanitization, the _sanitizeUrl function is passed instead of null.
// packages/core/src/render3/i18n/i18n_parse.ts (Patched)
export function i18nAttributesFirstPass(...) {
// ...
generateBindingUpdateOpCodes(
updateOpCodes,
previousElementIndex,
attrName,
countBindings(updateOpCodes),
URI_ATTRS[attrName.toLowerCase()] ? _sanitizeUrl : null, // <--- Dynamic sanitizer assignment
);
// ...
}Additionally, the patch hardens the TRUSTED_TYPES_SINKS schema in packages/compiler/src/schema/trusted_types_sinks.ts. By explicitly appending 'iframe|src' to the set of trusted type sinks, the compiler ensures that iframe sources are rigidly validated, closing a secondary vector for the same underlying bypass.
Exploitation of CVE-2026-32635 requires specific conditions within the target application's codebase. A developer must bind untrusted, user-controllable data to a sensitive HTML attribute while simultaneously enabling Angular's i18n translation for that exact attribute. The application must also lack strict Content Security Policy (CSP) headers that would otherwise block inline script execution.
An attacker constructs a specialized URI payload utilizing the javascript: protocol scheme. This payload is delivered to the application through standard input vectors, such as profile configuration fields, URL parameters, or manipulated API responses. The application then stores or reflects this payload into the vulnerable component's state.
When the Angular rendering engine processes the template, the i18nAttributesFirstPass function applies the payload directly to the DOM element without sanitization. For example, a template defined as <a [href]="userUrl" i18n-href>Link</a> will render as <a href="javascript:alert(document.domain)">Link</a>. User interaction, such as clicking the link, triggers immediate execution of the malicious script in the context of the vulnerable application.
CVE-2026-32635 carries a CVSS v4.0 base score of 8.6, reflecting a high severity rating. Successful exploitation grants an attacker arbitrary JavaScript execution capabilities within the victim's browser session. This access level permits the complete bypass of same-origin policy protections intended to isolate application contexts.
Once code execution is achieved, adversaries can hijack active authentication sessions by exfiltrating local storage, session storage, or non-HttpOnly cookies. The attacker can also perform unauthorized actions on behalf of the user by issuing authenticated API requests directly from the compromised client. This constitutes a severe violation of both system confidentiality and integrity.
The impact is magnified by the widespread use of Angular's i18n features in enterprise applications targeting global audiences. Applications that frequently handle user-supplied URLs, such as social platforms or content management systems, are at an elevated risk. The attack requires user interaction, but typical phishing or social engineering techniques make triggering the payload highly probable.
The definitive remediation for CVE-2026-32635 is updating the @angular/core and @angular/compiler packages to a patched release. Organizations must upgrade to versions 19.2.20, 20.3.18, 21.2.4, or 22.0.0-next.3 depending on their current release train. These versions contain the updated i18nAttributesFirstPass logic that correctly applies the _sanitizeUrl function.
If immediate patching is technically unfeasible, security teams can implement compensating controls via Content Security Policy (CSP). Deploying a strict CSP that prohibits unsafe-inline execution will neutralize the primary javascript: URI attack vector. Furthermore, restricting the base-uri and object-src directives adds defense-in-depth against variant payload structures.
Engineering teams should also consider enabling Trusted Types within the application architecture. Trusted Types compel the browser to reject dangerous string assignments to DOM sinks entirely. By configuring Angular to strictly enforce Trusted Types, the application gains runtime immunity to this class of DOM-based XSS, even if underlying framework vulnerabilities exist.
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N| Product | Affected Versions | Fixed Version |
|---|---|---|
@angular/compiler Angular | >= 22.0.0-next.0, < 22.0.0-next.3 | 22.0.0-next.3 |
@angular/compiler Angular | >= 21.0.0-next.0, < 21.2.4 | 21.2.4 |
@angular/compiler Angular | >= 20.0.0-next.0, < 20.3.18 | 20.3.18 |
@angular/compiler Angular | >= 17.0.0.next.0, < 19.2.20 | 19.2.20 |
@angular/core Angular | >= 22.0.0-next.0, < 22.0.0-next.3 | 22.0.0-next.3 |
@angular/core Angular | >= 21.0.0-next.0, < 21.2.4 | 21.2.4 |
@angular/core Angular | >= 20.0.0-next.0, < 20.3.18 | 20.3.18 |
@angular/core Angular | >= 17.0.0.next.0, < 19.2.20 | 19.2.20 |
| Attribute | Detail |
|---|---|
| Vulnerability Type | Cross-Site Scripting (XSS) |
| CWE ID | CWE-79 |
| CVSS v4.0 Score | 8.6 (High) |
| Attack Vector | Network |
| User Interaction | Required |
| Exploit Status | Proof of Concept Available |
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.