Previously, the compiler disallowed translation of any attribute starting with 'on' for security reasons. This incorrectly disallowed translation of the 'on' attribute itself, which is not an event handler.
This commit introduces `isPossibleEventHandler` to verify that the property name has a length greater than 2 in addition to starting with 'on'. This allows attributes like 'on' to be translated while still correctly disallowing actual event handlers like 'onerror', 'onclick', etc.
Apply schema-derived sanitizer resolution to TwoWayProperty ops so native two-way DOM bindings emit the same sanitizer as one-way property bindings.
Add compiler compliance coverage for innerHTML, srcdoc, URL, resource URL, and security-sensitive attribute cases.
(cherry picked from commit 9ca51ab0e4)
Updates the template preparser to exclude namespaced SVG style tags (':svg:style') from the style elements set.
Previously, ':svg:style' elements were incorrectly classified as PreparsedElementType.STYLE, which caused them to be completely stripped from the final template DOM tree during the Render3 template transform and pushed into standard component stylesheets. By limiting the style element parsing to standard 'style' tags, namespaced SVG style tags remain safely in the template AST as normal DOM elements, preserving local SVG styling.
Closes#68977
Removes the legacy profile property/attribute from the directives hostBindings specs to align with modern DOM security schema changes. Also cleans up minor redundant formatting lines in the compiler and core targets.
PR Close#68926
Normalize namespaced tag names (e.g., :xhtml:a to a) inside i18nResolveSanitizer before looking up their security context. This ensures custom namespaced tag attributes undergo correct translation sanitization at runtime.
PR Close#68926
Custom XML/XHTML namespaced elements (e.g., <xhtml:a>) fall back to the standard HTML namespace during element creation at compile-time/runtime. However, their property and security context lookups inside the schema registry were incorrectly performed using the full namespaced tag name (e.g., :xhtml:a), which bypassed the default a|href sanitization registry and incorrectly returned SecurityContext.NONE instead of SecurityContext.URL.
This commit introduces tag name normalization inside DomElementSchemaRegistry for custom namespaces (other than the built-in svg and math namespaces). Custom namespaced tag names are now normalized to their simple HTML element counterparts for all registry queries, ensuring that correct property schema validation and dynamic security sanitization rules (such as URL sanitization) are enforced at runtime.
PR Close#68926
Dynamic bindings to `href` and `xlink:href` attributes on SVG `<a>` elements (`<svg:a>`) 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 `<svg:a>` 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.
PR Close#68926
Ensures that namespaced <script> elements (such as :svg:script) are correctly classified as PreparsedElementType.SCRIPT by the template preparser and stripped during compilation to prevent potential XSS vulnerabilities. Consequently, obsolete security schema mappings and runtime sanitization checks for <script> attributes have been removed since these elements are never present in compiled template outputs.
PR Close#68926
Updates `DomElementSchemaRegistry` to strip `:svg:` and `:math:` namespace prefixes
from tag names before querying `SECURITY_SCHEMA` at compile-time. This allows SVG
and MathML attributes to correctly match their security contexts during compilation.
PR Close#68926
Refactors the element security schema lookups and runtime attribute validation to
consistently account for SVG and MathML namespaces. This improves the modularity
and accuracy of security context mapping during template compilation and runtime
constant evaluation, eliminating redundant or false-positive lifecycle checks.
PR Close#68926
Moves the event attribute validation check outside of `ngDevMode` in the `elementAttributeInternal` instruction to ensure that bindings to event attributes like `on*` are always blocked at runtime.
Previously, this check was only performed when `ngDevMode` was `true`, which could allow attacker-controlled CMS data to be bound to event attributes in production mode, causing browser-executed XSS.
Fixes#68419
PR Close#68468
This commit updates the DOM security schema and sanitization logic to properly recognize and sanitize `href` and `xlink:href` attributes on SVG `<script>` elements.
This commit implements a security fix to prevent XSS vulnerabilities where SVG animation elements (`<animate>`, `<set>`, etc.) could be used to modify the `href` or `xlink:href` attributes of other elements to `javascript:` URLs.
The fix introduces a runtime validation step:
- A new [ɵɵValidateAttribute](cci:1://file:///usr/local/google/home/alanagius/git/angular/packages/core/src/sanitization/sanitization.ts:276:0-288:1) instruction is used when `attributeName` is bound on SVG animation elements.
- If executed, a `RuntimeError` is thrown, preventing the binding.
- The compiler now identifies `attributeName` on SVG animation elements as security-sensitive and injects this validation.
Additionally, the DOM security schema has been updated to include a comprehensive list of MathML and SVG elements that accept `href` or `xlink:href` attributes, ensuring they are correctly treated as `SecurityContext.URL` and sanitized. This prevents malicious URLs from being bound to these attributes.
http://b/463880509
:nth-child() (and its siblings) support complex expressions, e.g.
`:nth-child(2n of :is(.foo, .bar))`. Previously we'd choke because of
the `:is()`. Now, we reuse the `_parenSuffix` subexpression to match
nested parentheses the same way we do for :host() and :host-context().
Note that we only support 3 levels of nesting, so a selector like
`:nth-child(n of :is(:has(:not(.foo))))` will still break.
I'll say yet again that we really should add a proper parser so we stop
getting bug reports like this :)
Fixes#64913
(cherry picked from commit 24cfd5a0ed)
I took a quick look at my recent changes to see if I had inadvertently
fixed this bug, but I couldn't seem to reproduce it even before my
changes. Seems like it's working, though.
Closes#58436
(cherry picked from commit 4b871b139b)
This change adds support for commas in :host() arguments (e.g.
`:host(:not(.foo, .bar))` as well as in nested parens when the argument
is applied without parens (e.g. `:host:not(:has(.foo, .bar))`).
Previously these selectors would receive an extra `[nghost]` attr, e.g.
`[nghost]:not(.foo, [nghost].bar)`.
I didn't file a bug for this one, but it's also blocking on an internal
LSC. Like the other CSS changes, I'll run a TGP to confirm this isn't
breaking.
Previously we supported one level of nested pseudo-element selectors
inside :host-context(), e.g. :host-context(:is(.foo, .bar)). This was
based on a regex-based approach. We could support deeper levels of
nesting by updating the regex, but using a regex approach prohibits us
from supporting arbitrary nesting.
Rather than just adding one more level to the existing expression, I've
added a new generator function which splits selectors on commas in a
parenthesis-aware way. This allows us to support arbitrary nesting.
It's likely we'll want to reuse this in other places where we're not as
careful today. We'll probably do this on a request-based basis, though.
Fixes#59176
This change adds support for commas in :host() arguments (e.g.
`:host(:not(.foo, .bar))` as well as in nested parens when the argument
is applied without parens (e.g. `:host:not(:has(.foo, .bar))`).
Previously these selectors would receive an extra `[nghost]` attr, e.g.
`[nghost]:not(.foo, [nghost].bar)`.
I didn't file a bug for this one, but it's also blocking on an internal
LSC. Like the other CSS changes, I'll run a TGP to confirm this isn't
breaking.
(cherry picked from commit 680c3c7bff)
Previously we supported one level of nested parentheses inside of a
`:host()` selector, e.g. `:host(:not(p))`. This caused a breakage in g3
when I migrated a selector from `:host:not(:has(p))` to
`:host(:not(:has(p)))`. This change adds support for just one more level
of nesting.
It'd be nice to move everything to a real CSS parser (or even update it
to count parentheses like I did with :host-context()), but I wasn't able
to get that to work in ~20 minutes and I'm focusing on other things at
the moment.
This change punts the problem until somebody tries to use just one more
level of nesting in a selector.
Fixes#64830
(cherry picked from commit 444143758e)
I've updated the test to assert what I believe it was trying to assert
before. Without this change, the CSS is invalid so it's unclear what
behavior we're demonstrating.
PR Close#64036
Fixes two issues that were preventing template literals from being recovered properly if one of the interpolated expressions is broken:
1. We weren't updating the expected brace counter when an interpolation starts which in turn was throwing off the recovery logic in `skip`.
2. When producing tokens for template literals, we were treating the closing brace as an operator whereas other places treat it as a character. Even after fixing the first issue, this was preventing the recovery logic from working correctly.
Fixes#63940.
PR Close#64150
angular#62630 made it so that all ARIA
property bindings would write to their corresponding attribute instead.
The primary motivation for this change was to ensure that ARIA
attributes were always rendered correctly on the server, where the
emulated DOM may not correctly reflect ARIA properties as attributes.
Furthermore, this change added support for binding to ARIA attributes
using the property binding syntax (e.g. `[aria-label]`).
Unfortunately, angular#62630 relied on
the incorrect assumptions that an ARIA property name could be converted
to its attribute name (without hardcoding the conversion), and that the
value of an ARIA property matched its corresponding attribute. For
example, the `ariaLabelledByElements` property's value is an array of
DOM elements, while the corresponding `aria-labelledby` attribute's
value is a string containing the IDs of the DOM elements.
This partially reverts angular#62630 so
that only property bindings with ARIA attribute names (begin with
`aria-`) are converted to attribute bindings.
* `[ariaLabel]` will revert to binding to the `ariaLabel` property.
* `[aria-label]` will continue binding to the `aria-label` attribute.
Note the only difference between `[aria-label]` and `[attr.aria-label]`
is that the former will attempt to bind to inputs of the same name while
the latter will not.
PR Close#64089
This updates the enter and leave logic to use the stored LView data to dispatch the enter and leave animations at the right points in the lifecycle. This should fix issues with signals not being available yet, parallel animations, and also eliminate the need for the element registry.
fixes: #63391fixes: #63388fixes: #63369
PR Close#63710
The new animations was not correctly looking for the `.` when parsing bindings. This resulted in arbitrary event bindings creating animate.leave instruction calls.
fixes: #63466
PR Close#63470
The animate instructions were getting applied to the container comment nodes as well as the element nodes. This prevents that on the compiler level.
fixes: #63371
PR Close#63390
Ts 5.9 introduced a regression coming from 5.8 when parenthesis aren't generated for expressions like (`(a ?? b) && c`).
This fix works around this explicitly specifying that we want to keep those parenthesis that we're aware of in this specific case;
This change can be reverted if the root issue (https://github.com/microsoft/TypeScript/issues/61369) is fixed. (but let's keep the tests in any case for the coverage)
fixes#63287
PR Close#63292
Host bindings for `(animate.enter)` and `(animate.leave)` were not firing properly. This fixes the compiler ingest to make sure they do fire.
fixes: #63199
PR Close#63217
Fixes that the pipeline wasn't processing the fallback content of `ng-content` for i18n which resulted in a compiler error further down the line.
Fixes#63065.
PR Close#63156