Which @angular/* package(s) are the source of the bug?
compiler/core
Is this a regression?
No
Description
Angular can choose the security context for a host binding from compile-time selector information, then later run that compiled host binding on a different concrete runtime host element.
This becomes unsafe when the selector used during compilation is not a sensitive element, but the runtime host is a sensitive browser sink such as:
- iframe[srcdoc]
- iframe[src]
- object[data]
- a[href]
In those cases Angular may emit or reuse host-binding code equivalent to:
attribute('srcdoc', ctx.srcdoc);
attribute('src', ctx.src);
attribute('data', ctx.data);
instead of applying sink-specific sanitization such as HTML sanitization for iframe[srcdoc] or ResourceURL enforcement for iframe[src] / object[data].
Affected composition paths
The same mismatch can be reached through at least these public Angular composition paths:
- hostDirectives
- inherited host bindings
- pure :not(...) selectors
- createComponent(..., {directives})
Cases
1. hostDirectives selector mismatch
The host directive is compiled from a custom-element selector where attr.srcdoc is not treated as an iframe[srcdoc] sink. The compiled host binding is then reused on an actual iframe host.
2. Inherited host-binding selector mismatch
The base directive host binding is compiled from a non-sensitive selector, then inherited by a component/directive whose runtime host is an iframe.
3. Pure :not(...) selector under-approximation
A pure :not(...) selector does not name the positive runtime element. Angular can compile the host binding without knowing that it will later run on an iframe.
4. Dynamic createComponent(..., {directives}) mismatch
This is the smallest self-contained case for an issue report. A component creates a real iframe host, then dynamically applies a directive whose host binding was compiled from a safe custom selector.
Related ResourceURL sinks
The same selector/runtime-host mismatch also affects document-loading sinks that should require ResourceURL handling, for example: [attr.src] & [attr.data]
Root cause
The sanitizer decision is bound too early or too narrowly for host bindings. Public composition APIs can later move or reuse a host binding on a different runtime host element. Dynamic component creation can also create a sensitive host element from a component selector and then write a host-bound sensitive sink.
When the final host/sink has a stricter security context than the compiled host binding applies, the write is not reclassified.
In short:
compiled host binding says: no sanitizer / weaker sanitizer
final host is: iframe, script, or object
binding writes: srcdoc/src/data
Angular uses: compiled weak/no-sanitizer context
browser receives: raw sensitive sink value
Please provide a link to a minimal reproduction of the bug
https://issuetracker.google.com/u/1/issues/513926480
Which @angular/* package(s) are the source of the bug?
compiler/core
Is this a regression?
No
Description
Angular can choose the security context for a host binding from compile-time selector information, then later run that compiled host binding on a different concrete runtime host element.
This becomes unsafe when the selector used during compilation is not a sensitive element, but the runtime host is a sensitive browser sink such as:
In those cases Angular may emit or reuse host-binding code equivalent to:
instead of applying sink-specific sanitization such as HTML sanitization for iframe[srcdoc] or ResourceURL enforcement for iframe[src] / object[data].
Affected composition paths
The same mismatch can be reached through at least these public Angular composition paths:
Cases
1. hostDirectives selector mismatch
The host directive is compiled from a custom-element selector where attr.srcdoc is not treated as an iframe[srcdoc] sink. The compiled host binding is then reused on an actual iframe host.
2. Inherited host-binding selector mismatch
The base directive host binding is compiled from a non-sensitive selector, then inherited by a component/directive whose runtime host is an iframe.
3. Pure :not(...) selector under-approximation
A pure :not(...) selector does not name the positive runtime element. Angular can compile the host binding without knowing that it will later run on an iframe.
4. Dynamic createComponent(..., {directives}) mismatch
This is the smallest self-contained case for an issue report. A component creates a real iframe host, then dynamically applies a directive whose host binding was compiled from a safe custom selector.
Related ResourceURL sinks
The same selector/runtime-host mismatch also affects document-loading sinks that should require ResourceURL handling, for example: [attr.src] & [attr.data]
Root cause
The sanitizer decision is bound too early or too narrowly for host bindings. Public composition APIs can later move or reuse a host binding on a different runtime host element. Dynamic component creation can also create a sensitive host element from a component selector and then write a host-bound sensitive sink.
When the final host/sink has a stricter security context than the compiled host binding applies, the write is not reclassified.
In short:
Please provide a link to a minimal reproduction of the bug
https://issuetracker.google.com/u/1/issues/513926480