Skip to content

fix(compiler): add URL sanitization for SVG animation value attributes#67927

Closed
mohammadmseet-hue wants to merge 1 commit intoangular:mainfrom
mohammadmseet-hue:fix/svg-animation-url-sanitization
Closed

fix(compiler): add URL sanitization for SVG animation value attributes#67927
mohammadmseet-hue wants to merge 1 commit intoangular:mainfrom
mohammadmseet-hue:fix/svg-animation-url-sanitization

Conversation

@mohammadmseet-hue
Copy link
Copy Markdown

Summary

The SVG animation elements (<animate>, <set>, <animateMotion>, <animateTransform>) have their attributeName binding correctly blocked via SecurityContext.ATTRIBUTE_NO_BINDING (see b/463880509#comment7). However, the value attributes (to, from, values, by) — which carry the actual data written to the animated attribute — have SecurityContext.NONE. No URL sanitization is applied to them.

When a developer uses a static attributeName="href" and binds an animation value to user-controlled data (e.g. [attr.to]="url"), an attacker can inject javascript: URIs that execute when the user clicks the animated SVG link.

The Bug

@Component({
  template: `
    <svg>
      <a>
        <set attributeName="href" [attr.to]="linkTarget" />
        <text y="20">Click me</text>
      </a>
    </svg>
  `
})
export class ExampleComponent {
  linkTarget = 'javascript:alert(document.cookie)';
}

Angular compiles [attr.to] with SecurityContext.NONE because set|to is not in the security schema:

DomElementSchemaRegistry.securityContext('set', 'to', true)
  → SECURITY_SCHEMA['set|to']   → NOT FOUND
  → SECURITY_SCHEMA['*|to']     → NOT FOUND
  → Returns: SecurityContext.NONE → No sanitization applied

The javascript: URI passes through unsanitized. The SVG animation engine writes it to the parent <a> element's href.animVal. Clicking the link executes JavaScript.

Compare with a standard <a> element, which is correctly sanitized:

Element Binding Rendered Sanitized?
<a [attr.href]="evil"> javascript:alert(1) unsafe:javascript:alert(1) Yes
<set attributeName="href" [attr.to]="evil"> javascript:alert(1) javascript:alert(1) No — bug

Browser Verification

Confirmed in Chromium 136. Clicking an SVG <a> element whose href was set via <set attributeName="href" to="javascript:alert(document.domain)"> triggered JavaScript execution, displaying "localhost".

Both <set> and <animate> vectors execute in Chrome, Firefox, and Safari.

The Fix

This commit adds all SVG animation value attributes to the SecurityContext.URL section of dom_security_schema.ts:

'animate|to', 'animate|from', 'animate|values', 'animate|by',
'set|to',
'animateMotion|to', 'animateMotion|from', 'animateMotion|values', 'animateMotion|by',
'animateTransform|to', 'animateTransform|from', 'animateTransform|values', 'animateTransform|by',

The URL sanitizer only blocks dangerous schemes (javascript:, vbscript:, data:) — it will not break legitimate animation values such as colors, numbers, or transform strings.

References

The SVG animation elements (`<animate>`, `<set>`, `<animateMotion>`,
`<animateTransform>`) have their `attributeName` binding correctly
blocked via `SecurityContext.ATTRIBUTE_NO_BINDING` to prevent attackers
from choosing which attribute to animate.

However, the value attributes (`to`, `from`, `values`, `by`) that
carry the actual data written to the animated attribute have
`SecurityContext.NONE` — no URL sanitization is applied.

When a developer uses `attributeName="href"` (statically) and binds
the animation value to user-controlled data (e.g. `[attr.to]="url"`),
an attacker can inject `javascript:` URIs that execute when the user
clicks the animated SVG link. This is confirmed to execute in
Chromium, Firefox, and Safari.

This commit adds all SVG animation value attributes to the
`SecurityContext.URL` section of the DOM security schema. The URL
sanitizer only blocks dangerous schemes (`javascript:`, `vbscript:`,
`data:`) — it will not break legitimate animation values such as
colors, numbers, or transform strings.
@angular-robot angular-robot bot added the area: compiler Issues related to `ngc`, Angular's template compiler label Mar 29, 2026
@ngbot ngbot bot added this to the Backlog milestone Mar 29, 2026
@alan-agius4
Copy link
Copy Markdown
Contributor

alan-agius4 commented Mar 29, 2026

Duplicate of #67797

@alan-agius4 alan-agius4 marked this as a duplicate of #67692 Mar 29, 2026
@alan-agius4 alan-agius4 marked this as a duplicate of #67797 Mar 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: compiler Issues related to `ngc`, Angular's template compiler

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants