CVE-2026-32635: Cross-Site Scripting (XSS) in Angular i18n Attribute Bindings
How Angular’s i18n attribute bindings bypass built-in sanitization and expose applications to cross-site scripting attacks.
.png)
How Angular's internationalization feature can bypass built-in sanitization on security-sensitive HTML attributes
Open source powers the modern software stack, but its security depends on a shared commitment to finding and fixing weaknesses before they become incidents.
At HeroDevs, that's our mission: secure open source. We do it in two ways:
- Remediating known CVEs across critical ecosystems, and
- Proactively researching vulnerabilities before attackers can exploit them.
A high-severity XSS vulnerability, CVE-2026-32635, has been disclosed in the Angular runtime and compiler. It affects how Angular handles attribute bindings when those attributes are marked for internationalization using Angular's i18n- prefix. Patches are available for Angular 19, 20, 21, and 22-next, but Angular 17 and 18 are end-of-life and will not receive a community fix.
What is CVE-2026-32635?
CVE-2026-32635 is a cross-site scripting (XSS) vulnerability that occurs when an Angular application uses a security-sensitive HTML attribute (such as href, src, or action) in combination with Angular's internationalization (i18n) system.
Angular provides built-in sanitization that automatically cleans dangerous values bound to sensitive attributes. For example, binding a javascript: URL to an href attribute is normally blocked by Angular's DomSanitizer. However, adding the i18n-href attribute to the same element tells Angular's compiler to route that attribute through the i18n pipeline instead, and this codepath bypasses the sanitization entirely.
The result: untrusted user input bound to a sensitive attribute can execute arbitrary JavaScript in the victim's browser.
High Severity, Low Barrier to Exploit
The Angular team published this vulnerability with a CVSS v4 score of 8.6 (High), using the vector:
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
That score reflects several things worth unpacking:
- Attack Complexity is Low. There's no special configuration required beyond the vulnerable pattern itself.
- User Interaction is Passive. The victim only needs to visit a page containing the malicious payload; no clicking, form submission, or other active participation is required.
- Confidentiality, Integrity, and Availability impacts are all High. Once script execution is achieved in the user's browser context, the attacker has broad access to session tokens, DOM content, and can perform actions on behalf of the user.
Root cause: i18n attribute processing bypasses DomSanitizer
At the center of this vulnerability is how Angular's compiler handles attributes that are annotated for translation.
Angular's template compiler recognizes the i18n-<attribute> pattern as a signal that the attribute value should be processed through the internationalization pipeline. When an attribute like href is marked with i18n-href, the compiler routes the binding through a different code path than the standard property binding.
The standard path applies DomSanitizer to security-sensitive contexts. The i18n path does not.
Here is the vulnerable pattern:
<a [href]="userProvidedUrl" i18n-href>Click me</a>Without i18n-href, Angular would sanitize userProvidedUrl and strip any javascript: scheme or other dangerous content. With i18n-href present, that sanitization step is skipped, and the raw value is rendered directly into the DOM.
The following attributes have been confirmed as vulnerable when paired with their corresponding i18n- prefix:
- action
- background
- cite
- codebase
- data
- formaction
- href
- itemtype
- longdesc
- poster
- src
- xlink:href
The practical issue is straightforward: if an application binds untrusted data to any of these attributes and also marks them for i18n, Angular's primary defense against XSS is silently disabled.
Understanding the exploit: sanitization bypass via i18n
The easiest way to reason about this is to model the two paths a bound value can take through the compiler.
Path A: Standard binding (safe)
A developer writes a standard template binding:
<a [href]="userUrl">Visit</a>Angular's compiler generates code that passes userUrl through DomSanitizer.sanitize(SecurityContext.URL, userUrl) before applying the value to the DOM. If userUrl contains javascript:alert(document.cookie), the sanitizer strips it and the link becomes inert.
Path B: i18n-annotated binding (vulnerable)
A developer adds the i18n attribute for translation support:
<a [href]="userUrl" i18n-href>Visit</a>
The Angular compiler now treats the href as an i18n-managed attribute. The binding value passes through the internationalization pipeline, which handles message extraction and substitution but does not invoke the security sanitizer. The same javascript:alert(document.cookie) payload reaches the DOM untouched.
That is the core of CVE-2026-32635: a feature meant for localization inadvertently creates a bypass around Angular's XSS protections.
Attack preconditions
This vulnerability becomes exploitable when all of the following conditions are met:
- The application runs a vulnerable version of Angular.
- A template binds untrusted user input (from a database, API response, URL parameter, or similar source) to one of the sensitive attributes listed above.
- That same attribute is annotated for internationalization with a corresponding i18n-<attribute> directive.
The third condition is the critical factor. Many Angular applications use i18n, and many bind dynamic data to attributes like href or src. What makes this dangerous is that developers who add i18n-href for a legitimate localization reason may not realize they are simultaneously removing a security boundary.
What this means in practice
When exploited, this vulnerability enables an attacker to execute arbitrary JavaScript in the context of the vulnerable application's domain. The impacts include:
Session hijacking. An attacker can steal session cookies and authentication tokens, gaining access to the victim's account without credentials.
Data exfiltration. Sensitive data visible in the DOM or accessible via the application's APIs can be captured and transmitted to an attacker-controlled server.
Unauthorized actions. The attacker can perform any action the victim is authorized to do: submitting forms, changing settings, initiating transactions, or escalating privileges.
Credential theft. The attacker can inject fake login forms or redirect the user to phishing pages that appear to be part of the legitimate application.
These are the standard consequences of any XSS vulnerability, but the high CVSS score reflects the fact that the attack surface here is broad (network-accessible, low-complexity) and the required user interaction is passive.
Angular's open source security support lifecycle
Angular follows a predictable release and support cadence. Each major version receives 6 months of active support followed by 12 months of long-term support (LTS), for a total of 18 months of community-backed security coverage. After that window closes, the version reaches end-of-life (EOL) and receives no further patches from the Angular team, regardless of severity.
Here is where the currently affected versions stand:

Two things are worth emphasizing here.
Angular 17 and 18 are confirmed vulnerable and will never receive a community fix. The GitHub advisory explicitly lists >= 17.0.0.next.0, <= 18.2.14 as affected with no patched version. If your application is running Angular 17 or 18, you are exposed to this XSS vulnerability with no path to resolution through the open source project.
Angular 19's end-of-life is approximately two months away (May 19, 2026). While a patch (19.2.20) is available today, Angular 19 will stop receiving security fixes after that date. Any new vulnerability discovered after May 2026 will not be addressed in Angular 19 by the community. If your team is running Angular 19 and cannot upgrade to 20 or 21 before that deadline, you will soon be in the same position that Angular 17 and 18 users are in now.
Mitigation guidance
If you are responsible for an Angular application:
Upgrade to a patched version. If you are on Angular 19, 20, or 21, update to 19.2.20, 20.3.18, or 21.2.4 respectively. This is the fastest path to remediation for supported versions.
Audit your templates for the vulnerable pattern. Search your codebase for any i18n- prefixed attributes that also bind dynamic data. The pattern to look for is any element where a security-sensitive attribute (like href, src, action) is both data-bound and marked for i18n. A targeted search for i18n-href, i18n-src, i18n-action, and the other affected attributes is a good starting point.
Apply manual sanitization as a workaround. If you cannot upgrade immediately, you can explicitly pass bound values through Angular's DomSanitizer before they reach the template. The workaround from the Angular team looks like this:
import { Component, inject, SecurityContext } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
@Component({
template: `
<a [href]="sanitizedUrl" i18n-href>Click me</a>
`,
})
export class ExampleComponent {
sanitizedUrl: string;
constructor() {
const untrustedInput = getValueFromExternalSource();
const sanitizer = inject(DomSanitizer);
this.sanitizedUrl =
sanitizer.sanitize(SecurityContext.URL, untrustedInput) || '';
}
}
This approach re-introduces the sanitization step that the i18n codepath skips, but it requires manual effort for every affected binding and is easy to miss during future development.
If you are on Angular 17 or 18, there is no community patch available. Your options are to upgrade to a supported Angular version (which can be a significant effort involving breaking changes across multiple major versions) or to adopt commercial long-term support.
HeroDevs Never-Ending Support for Angular
HeroDevs provides Never-Ending Support (NES) for Angular, delivering security patches for all end-of-life Angular versions as secure, drop-in replacements. NES for Angular covers versions 4 through 18 today, with support for Angular 19 available the day it reaches EOL.
For CVE-2026-32635 specifically, HeroDevs NES customers on Angular 17 and 18 receive a patched version that addresses this vulnerability, something the open source project will never provide for those versions.
If your organization depends on Angular 17, 18, or soon-to-be-EOL Angular 19, and cannot complete a major-version upgrade on the timeline the community support window demands, contact HeroDevs to learn how NES can keep your applications secure and compliant while you plan your migration on your own schedule.
Taking action
CVE-2026-32635 is a clear example of how feature interactions in a mature framework can create unexpected security gaps. Angular's i18n system and its DomSanitizer are both well-designed in isolation. The vulnerability arises specifically at the intersection of the two, where the i18n compiler path does not invoke the sanitization that developers (and security auditors) expect to be always-on.
For teams on supported Angular versions, the fix is straightforward: update to the latest patch release. For teams on Angular 17 or 18, the situation is more urgent. The vulnerability is confirmed, the affected versions are enumerated in the advisory, and no community fix is coming.
If your organization depends on open source frameworks at scale, this is exactly the kind of gap that commercial long-term support exists to close: keeping your applications secure after the community moves on.
.png)
.png)
.png)