From 128553fb97aea04e943f27dd07ce098255f952f0 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Thu, 21 May 2026 18:49:56 +0000 Subject: [PATCH 1/4] fix(compiler): sanitize dynamic href and xlink:href bindings on SVG a elements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dynamic bindings to `href` and `xlink:href` attributes on SVG `` elements (``) were previously unmapped in the DOM security schema. As a result, they bypassed sanitization completely, creating a potential XSS vulnerability if bound to untrusted user inputs (e.g., `javascript:` URLs). This fix mitigates this risk by: 1. Registering `href` and `xlink:href` on `` elements under the `SecurityContext.URL` context in both the compiler and core DOM security schemas. 2. Enabling template compilation to output runtime URL sanitization checks (`ɵɵsanitizeUrl`) on these attributes. 3. Adding regression and verification test cases to ensure dynamic SVG link bindings are safely sanitized at runtime while static values are correctly allowed. --- .../src/schema/dom_security_schema.ts | 2 + .../dom_element_schema_registry_spec.ts | 6 +++ .../src/sanitization/dom_security_schema.ts | 2 + .../core/test/acceptance/security_spec.ts | 54 +++++++++++++++++++ 4 files changed, 64 insertions(+) diff --git a/packages/compiler/src/schema/dom_security_schema.ts b/packages/compiler/src/schema/dom_security_schema.ts index 12a674b7021f..1acc4ede7df7 100644 --- a/packages/compiler/src/schema/dom_security_schema.ts +++ b/packages/compiler/src/schema/dom_security_schema.ts @@ -115,6 +115,8 @@ export function SECURITY_SCHEMA(): {[k: string]: SecurityContext} { ['object', ['codebase', 'data']], ]); + registerContext(SecurityContext.URL, SVG_NAMESPACE, [['a', ['href', 'xlink:href']]]); + // Keep this in sync with SECURITY_SENSITIVE_ELEMENTS in packages/core/src/sanitization/sanitization.ts // The `unknown` elements refer to cases when we need to validate the input/binding in a directive (host bindings) // and the directive can be applied to multiple different elements (with different tag names). In this case we generate diff --git a/packages/compiler/test/schema/dom_element_schema_registry_spec.ts b/packages/compiler/test/schema/dom_element_schema_registry_spec.ts index d11760732d41..203b9f700d8f 100644 --- a/packages/compiler/test/schema/dom_element_schema_registry_spec.ts +++ b/packages/compiler/test/schema/dom_element_schema_registry_spec.ts @@ -168,6 +168,12 @@ If 'onAnything' is a directive input, make sure the directive is imported by the expect(registry.securityContext(':svg:set', 'to', false)).toBe( SecurityContext.ATTRIBUTE_NO_BINDING, ); + + // SVG link attributes + expect(registry.securityContext(':svg:a', 'href', false)).toBe(SecurityContext.URL); + expect(registry.securityContext(':svg:a', 'xlink:href', false)).toBe(SecurityContext.URL); + expect(registry.securityContext(':svg:a', 'href', true)).toBe(SecurityContext.URL); + expect(registry.securityContext(':svg:a', 'xlink:href', true)).toBe(SecurityContext.URL); }); it('should detect properties on namespaced elements', () => { diff --git a/packages/core/src/sanitization/dom_security_schema.ts b/packages/core/src/sanitization/dom_security_schema.ts index 12a674b7021f..1acc4ede7df7 100644 --- a/packages/core/src/sanitization/dom_security_schema.ts +++ b/packages/core/src/sanitization/dom_security_schema.ts @@ -115,6 +115,8 @@ export function SECURITY_SCHEMA(): {[k: string]: SecurityContext} { ['object', ['codebase', 'data']], ]); + registerContext(SecurityContext.URL, SVG_NAMESPACE, [['a', ['href', 'xlink:href']]]); + // Keep this in sync with SECURITY_SENSITIVE_ELEMENTS in packages/core/src/sanitization/sanitization.ts // The `unknown` elements refer to cases when we need to validate the input/binding in a directive (host bindings) // and the directive can be applied to multiple different elements (with different tag names). In this case we generate diff --git a/packages/core/test/acceptance/security_spec.ts b/packages/core/test/acceptance/security_spec.ts index 4122b9aa40a4..8722b4b9c555 100644 --- a/packages/core/test/acceptance/security_spec.ts +++ b/packages/core/test/acceptance/security_spec.ts @@ -916,3 +916,57 @@ describe('SVG