diff --git a/packages/compiler/src/render3/view/i18n/meta.ts b/packages/compiler/src/render3/view/i18n/meta.ts
index f5071b3f8fc5..8029f72c00f2 100644
--- a/packages/compiler/src/render3/view/i18n/meta.ts
+++ b/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.`,
diff --git a/packages/core/test/linker/security_integration_spec.ts b/packages/core/test/linker/security_integration_spec.ts
index bf888bead209..3c66158772f0 100644
--- a/packages/core/test/linker/security_integration_spec.ts
+++ b/packages/core/test/linker/security_integration_spec.ts
@@ -348,6 +348,15 @@ describe('security integration tests', function () {
expect(link.getAttribute('href')).toEqual('unsafe:javascript:alert(1)');
});
+ it('should throw error on translated event attributes', () => {
+ const template = `
`;
+ TestBed.overrideComponent(SecuredComponent, {set: {template}});
+
+ expect(() => TestBed.createComponent(SecuredComponent)).toThrowError(
+ /Translating attribute 'onerror' is disallowed for security reasons./,
+ );
+ });
+
it('should throw error on security-sensitive attributes with constant values', () => {
const template = ``;
TestBed.overrideComponent(SecuredComponent, {set: {template}});