Skip to content

feat(core): support prefix-insensitive DOM schema lookups and compile-time i18n attribute validation#68591

Merged
leonsenft merged 6 commits into
angular:mainfrom
alan-agius4:i18n-sec
May 19, 2026
Merged

feat(core): support prefix-insensitive DOM schema lookups and compile-time i18n attribute validation#68591
leonsenft merged 6 commits into
angular:mainfrom
alan-agius4:i18n-sec

Conversation

@alan-agius4
Copy link
Copy Markdown
Contributor

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.

Also implements dynamic schema-based sanitization and validation for static i18n attributes by wrapping `` expressions directly in their core sanitizers and validators at compile-time via an optimized switch statement.

Additionally, updates the runtime i18n parser to dynamically resolve sanitizers based on the SECURITY_SCHEMA registry and cleans up type assertions inside ɵɵvalidateAttribute to safely support evaluation when no TNode is selected.

@angular-robot angular-robot Bot added detected: feature PR contains a feature commit area: core Issues related to the framework runtime labels May 6, 2026
@ngbot ngbot Bot added this to the Backlog milestone May 6, 2026
@alan-agius4 alan-agius4 force-pushed the i18n-sec branch 3 times, most recently from c004f1b to cee01f9 Compare May 6, 2026 12:10
Comment thread packages/core/test/linker/security_integration_spec.ts
// value of that attribute is updated to read the extracted i18n variable.
const attributesForMessage = extractedAttributesByI18nContext.get(op.i18nContext);
if (attributesForMessage !== undefined) {
for (const attr of attributesForMessage) {
Copy link
Copy Markdown
Contributor Author

@alan-agius4 alan-agius4 May 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we run the santizer here or outright reject this in translations for such attributes?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Alan. To keep this aligned with the discussion from #68559: I agree the right fix should be centralized and schema-driven, not split into per-attribute patches.

My main concern is preserving the security invariant consistently:

translated static i18n attributes should not bypass the sanitizer/validator path Angular applies to the same security-sensitive tag/attribute pair elsewhere.

So I think the expected behavior should be:

  • non-security-sensitive translated attributes remain allowed;
  • URL / HTML / STYLE contexts are sanitized;
  • RESOURCE_URL fails closed, because translated strings should not become trusted executable resource URLs;
  • ATTRIBUTE_NO_BINDING goes through validateAttribute / rejection, because those attributes are not safely sanitizable.

The current #68591 direction appears to cover the concrete cases I reported across #68557, #68559, #68560, and #68580. My priority is to help make the broader hardening complete and robust rather than keep fragmented fixes open.

The only extra hardening point I would keep an eye on is namespace normalization anywhere SECURITY_SCHEMA is queried, especially SVG/MathML paths such as :svg:script, :svg:set, and MathML href / xlink:href, plus avoiding drift between the compiler-side and runtime/core schema
copies.

Hope this helps you and the team. Happy to test any extra cases if useful.

Comment thread packages/compiler/src/schema/dom_element_schema_registry.ts Outdated
Comment thread packages/compiler/src/schema/dom_element_schema_registry.ts Outdated
Comment thread packages/core/test/linker/security_integration_spec.ts Outdated
Comment thread packages/core/test/linker/security_integration_spec.ts Outdated
Comment thread packages/core/test/linker/security_integration_spec.ts
Comment thread packages/compiler/src/schema/dom_security_schema.ts
if (!ir.isStringLiteral(value)) {
throw Error('AssertionError: extracted attribute value should be string literal');
}
if (trustedValueFn !== null && ir.isStringLiteral(value)) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this change relevant/required?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes

Comment thread packages/compiler/src/schema/dom_security_schema.ts
@alan-agius4 alan-agius4 force-pushed the i18n-sec branch 2 times, most recently from b6efa18 to f54d970 Compare May 11, 2026 08:57
}

if (typeof validationConfig !== 'boolean') {
if (!tNode) {
Copy link
Copy Markdown
Member

@alxhub alxhub May 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious about the !tNode condition- why does lack of aTNode` mean something from a security standpoint?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From a security standpoint, a TNode represents a safely tracked, statically verified element.

If attribute validation is triggered dynamically via a runtime binding instruction but the TNode is missing, it implies an untracked assignment such as arbitrary renderer calls or unverified directive host attribute bindings. Because we cannot inspect the physical template element in these contexts to confirm the target DOM state is safe (e.g., verifying what property an tag is targeting), it treats the dynamic assignment as a potential injection risk. This is because static i18n attributes are evaluated early inside the consts array definition before any elements are created.

Comment thread packages/compiler/src/template/pipeline/src/phases/i18n_const_collection.ts Outdated
Comment thread packages/compiler/src/compiler.ts Outdated
@alan-agius4 alan-agius4 marked this pull request as ready for review May 12, 2026 07:28
@pullapprove pullapprove Bot requested a review from josephperrott May 12, 2026 07:28
@alan-agius4 alan-agius4 added action: review The PR is still awaiting reviews from at least one requested reviewer target: patch This PR is targeted for the next patch release and removed detected: feature PR contains a feature commit labels May 12, 2026
Comment thread packages/core/BUILD.bazel
cmd = "cp $< $@",
)

write_source_file(
Copy link
Copy Markdown
Contributor Author

@alan-agius4 alan-agius4 May 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alxhub, I went with the bazel approach. This under the hood has also a diff test.

@alan-agius4
Copy link
Copy Markdown
Contributor Author

Caretaker note: this requires a G3 patch https://critique.corp.google.com/cl/917087656

@alan-agius4 alan-agius4 added the merge: caretaker note Alert the caretaker performing the merge to check the PR for an out of normal action needed or note label May 18, 2026
Copy link
Copy Markdown
Member

@alxhub alxhub left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed-for: fw-general, fw-compiler, fw-security

…time i18n attribute validation

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.

Also implements dynamic schema-based sanitization and validation for static i18n
attributes by wrapping `` expressions directly in their core sanitizers and
validators at compile-time via an optimized `switch` statement.

Additionally, updates the runtime i18n parser to dynamically resolve sanitizers based
on the `SECURITY_SCHEMA` registry and cleans up type assertions inside `ɵɵvalidateAttribute` to safely support evaluation when no `TNode` is selected.
Copy link
Copy Markdown
Member

@josephperrott josephperrott left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Reviewed-for: fw-security

@pullapprove pullapprove Bot requested review from atscott and kirjs May 19, 2026 13:53
@alan-agius4 alan-agius4 added action: review The PR is still awaiting reviews from at least one requested reviewer and removed action: review The PR is still awaiting reviews from at least one requested reviewer labels May 19, 2026
Copy link
Copy Markdown
Member

@JeanMeche JeanMeche left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reviewed-for: public-api

Copy link
Copy Markdown
Contributor

@AndrewKushnir AndrewKushnir left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed-for: size-tracking

@alan-agius4 alan-agius4 removed request for atscott and kirjs May 19, 2026 15:09
@alan-agius4 alan-agius4 added action: merge The PR is ready for merge by the caretaker target: rc This PR is targeted for the next release-candidate and removed action: review The PR is still awaiting reviews from at least one requested reviewer target: patch This PR is targeted for the next patch release labels May 19, 2026
@leonsenft leonsenft merged commit 61a97f2 into angular:main May 19, 2026
30 of 31 checks passed
@leonsenft
Copy link
Copy Markdown
Contributor

This PR was merged into the repository. The changes were merged into the following branches:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

action: merge The PR is ready for merge by the caretaker area: core Issues related to the framework runtime merge: caretaker note Alert the caretaker performing the merge to check the PR for an out of normal action needed or note target: rc This PR is targeted for the next release-candidate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants