Imported from VincentChuWaiChow/vanguard-frontier-agentic (
skills/frontend/angular-template-sanitizer-security-review/SKILL.md). Install upstream withnpx skills add VincentChuWaiChow/vanguard-frontier-agentic --skill angular-template-sanitizer-security-review. Copyright stays with the author.
Angular Template Sanitizer Security Review
Purpose
Review Angular templates, components, and their data-flow for the documented injection classes Angular's own sanitizer architecture is built to catch, and that are only unsafe when application code deliberately or accidentally routes around it: DomSanitizer bypass calls (bypassSecurityTrustHtml, bypassSecurityTrustUrl, bypassSecurityTrustResourceUrl) fed by user-reachable input, unsanitized [innerHTML] bindings, and dynamically bound iframe security attributes such as [attr.sandbox] that Angular's own NG0910 check exists to reject. This skill exists so the review stays anchored to these documented, concrete sinks instead of drifting into a general "Angular code review" — it does not re-litigate change detection, signals architecture, or component design in every response.
When to use
Use this skill when the user asks to:
- review whether a
bypassSecurityTrustHtml,bypassSecurityTrustUrl, orbypassSecurityTrustResourceUrlcall is safe, - assess whether an
[innerHTML]binding is safe, - review an
<iframe>embed for a dynamically bound security attribute ([attr.sandbox],[sandbox],[attr.allow],[attr.credentialless]) or an NG0910 error, - perform a pre-launch security review of Angular templates that render user- or third-party-supplied content.
Do not use this skill for:
- Angular architecture review with no security angle (signals usage, change-detection strategy, component decomposition quality) — use
angular-architecture-signals-reviewinstead, - SSR/hydration-specific defects (
TransferStateleakage, hydration mismatches) — useangular-ssr-hydration-reviewinstead, - a bug that requires live traffic reproduction (a captured XSS payload in a running app, a browser-based exploit proof) to confirm exploitation — static analysis proves the structural risk, not that it has already been exploited in production.
Context7 Documentation Protocol
- Resolve the Angular library ID with
resolve-library-id(matched result:/angular/angular) before citing any sanitizer-mechanism or NG0910 claim. /angular/angularis Angular's own source-and-docs repository (high reputation, corroborated againstpackages/platform-browser/src/security/dom_sanitization_service.ts,packages/core/src/sanitization/html_sanitizer.ts,packages/core/src/render3/instructions/shared.ts, andadev/src/content/reference/errors/NG0910.md). Usequery-docsagainst it to confirm low-level sanitizer mechanics directly from source: thatbypassSecurityTrustHtml(and its URL/resource-URL siblings) mark a value trusted sosanitize()skips the HTML/URL sanitizer and returns the value unchanged, that property bindings like[innerHTML]accept a compiler-added sanitizer function that only risky properties receive, and that text interpolation instead callsrenderer.setValue()on a text node — a path that never parses HTML and needs no sanitizer.- Before flagging a
[attr.sandbox]/[sandbox]/[attr.allow]/[attr.credentialless]binding, confirm Angular's own NG0910 check: these attributes are documented as required to be static (fixed at element-creation time) because they configure the iframe's security model beforesrc/srcdocload — a dynamic binding either throws NG0910 in dev or, if that check is suppressed, lets a runtime value weaken the sandbox. - Read the component's imports first to confirm
DomSanitizer(from@angular/platform-browser) is actually in use before assuming a bypass call exists — do not assume a project uses the bypass APIs without confirming the import and call site. - If Context7 is unavailable, fall back to the
official_docsURLs in this skill'smetadata.jsonand label the claimdocumentation-based, unverified against current release.
Lean operating rules
- Injection findings default to HIGH severity. This is a security-scoped skill: do not downgrade an untraced
bypassSecurityTrustHtml/bypassSecurityTrustUrl/bypassSecurityTrustResourceUrlcall or an unsanitized[innerHTML]binding to MEDIUM just because it has not been observed exploited yet — the risk is in the structure, not in whether someone has already hit it. - Trace every finding to a concrete file:line and a concrete data-flow path. A finding that says "this bypass call might be unsafe" or "this innerHTML might be risky" without showing the specific origin (route param, query string, request body, or a third-party API response that itself echoes user input) and the specific sink is not a valid finding — it is a guess.
- Do not approve any
bypassSecurityTrustHtml,bypassSecurityTrustUrl, orbypassSecurityTrustResourceUrlcall whose input includes user-reachable data unless the trace shows the value was validated or sanitized on that exact path before the bypass call — the bypass APIs are intentional escape hatches from Angular's compiler-driven sanitization, not accidental gaps, so their mere presence is not evidence of prior review. - Do not approve an
[innerHTML]binding fed by user-reachable input unless a named sanitizer call (e.g.,DomSanitizer.sanitize(SecurityContext.HTML, ...), or a project-specific equivalent) is visibly present on that exact data-flow path. A sanitizer import existing elsewhere in the codebase does not clear this bar — trace the specific path under review. - Flag any
[attr.sandbox],[sandbox],[attr.allow], or[attr.credentialless]binding on an<iframe>as a finding regardless of whether NG0910 is currently thrown in the reviewed environment — a suppressed or bypassed dev-mode check does not make the underlying dynamic-security-attribute pattern safe in production. - Check dynamic
[href]/[src]bindings fed throughbypassSecurityTrustUrl/bypassSecurityTrustResourceUrlfor scheme validation (an allowlist rejectingjavascript:and other non-http(s)schemes) on the traced path before the bypass call — the bypass call itself performs no validation. - Never execute, build, or run application code, and never send live requests, as part of this review; this is a static-review skill (Read/Grep/Glob only).
- Load only the reference needed for the concern in scope.
References
Load these only when needed:
- Review workflow and findings contract — use for the step-by-step review procedure, the sanitizer-bypass/innerHTML/iframe decision tree, and the required output shape.
- DomSanitizer bypass calls and innerHTML — load only when the review scope includes a
bypassSecurityTrustHtml/bypassSecurityTrustUrl/bypassSecurityTrustResourceUrlcall or an[innerHTML]binding. Includes the OWASP XSS grounding reference; load that citation only when a finding is actually present. - Dynamic iframe security attributes — load only when the review scope includes an
<iframe>element with a boundsandbox,allow, orcredentiallessattribute, or a reported NG0910 error.
Response minimum
Return, at minimum:
- the component(s), template binding(s), and/or
DomSanitizercall site(s) in scope, - ranked findings with file:line evidence, defect category (
xss,url-injection, oriframe-sandbox-escape), the concrete data-flow trace (origin-to-sink path naming every hop), and a fix sketch matching Angular's documented pattern, - for every bypass call or
[innerHTML]finding, an explicit statement of whether validation or sanitization is present on the traced path — never approve on the assumption one exists elsewhere, - evidence level per finding (
repo evidence,documentation-based, orinference), with structural risk findings explicitly labeled as structural risk, not as confirmed-exploited, - verdict (approve / approve-with-notes / block),
- open questions or scope the review could not cover (e.g., "confirming actual exploitation requires a live payload test in a running browser session, not static review").