highCVE-2026-69151Aug 3, 2026

CVE-2026-69151: @angular/compiler i18n Event-Handler Attribute XSS

Shubham Kandhare
Security Engagement Manager, SecureLayer7

A flaw in Angular's i18n compiler pipeline lets a malicious translation file inject arbitrary JavaScript into event-handler attributes like onerror, bypassing Angular's own attribute safety checks.

Package@angular/compiler
Ecosystemnpm
Affected>= 22.0.0-next.0, < 22.0.1
Fixed in22.0.1
CVE-2026-69151: @angular/compiler i18n Event-Handler Attribute XSS

The problem

Angular's compiler validates attribute bindings through validateAttribute() and validateProperty(), which block direct binding to event-handler attributes such as onerror or onclick.

The i18n metadata collection path, however, had no equivalent guard. A developer could mark a static event-handler attribute for translation using the i18n-on* prefix (e.g., i18n-onerror). At localization-merge time, a lower-trust translation file could then replace the static value with arbitrary JavaScript, producing a compiled output that executes attacker-controlled code in the browser.

Proof of concept

A working proof-of-concept for CVE-2026-69151 in @angular/compiler, with the exact payload below.

html
<!-- Template (developer-written, Angular >= 22.0.0) -->
<img src="photo.jpg" onerror="void 0" i18n-onerror />

<!-- Attacker-controlled XLIFF translation file (e.g., messages.fr.xlf) -->
<!-- The translation target replaces "void 0" with the malicious handler value -->
<trans-unit id="onerror-msg">
  <source>void 0</source>
  <target>alert(document.cookie)</target>
</trans-unit>

<!-- Compiled localized output after `ng build --localize` -->
<img src="photo.jpg" onerror="alert(document.cookie)" />

The root cause is a missing validation gate in the i18n attribute metadata collector. validateAttribute() already rejects on* names for data-bound attributes, but the i18n-<name> collection path never called the same check, so i18n-onerror, i18n-onclick, etc. were silently accepted.

The patch (commits 417a4071 and 6c41f5ca, PRs #68821 and #69306) added an explicit guard to "disallow i18n event attributes" and refined the event-handler detection to "restrict possible event handler check to property names longer than 2 characters" to avoid false-positives on trivially short names.

Any i18n-on* attribute targeting a name longer than two characters after on is now a compile-time error.

This is CWE-79: Improper Neutralization of Input During Web Page Generation. The threat model requires an attacker who can influence translation files, a realistic scenario when translations are outsourced or loaded from a partially trusted external source.

The fix

Upgrade @angular/compiler (and the rest of the Angular toolchain) to 22.0.1, 21.2.19, or 20.3.27. If an immediate upgrade is not possible, audit all templates for any i18n-on* attributes and remove them. Never mark event-handler attributes for translation, and ensure translation files are sourced only from fully trusted, version-controlled origins.

Reporter not attributed.

References: [1][2][3][4][5][6]

Related research