Security
Priority: P0 (CRITICAL)
Principles
- XSS Prevention: Angular sanitizes interpolated values by default — {{ userInput }} safe. NOT use
innerHTMLunless absolutely necessary (e.g., trusted static CMS content). For user-generated content, display as text with {{ content }} — never as HTML. - Trusted HTML APIs: Mark HTML as trusted only for content you control (e.g., vetted CMS headers). Never mark user-provided data as trusted. Prefer DomSanitizer.sanitize(SecurityContext.HTML, content) and review every trust-marking call as a potential XSS vector.
- Route Guards: Protect all sensitive routes with functional CanActivateFn (e.g., inject(Router).createUrlTree(['/login'])). Apply with canActivate: [authGuard].
Guidelines
- CSP: Configure CSP headers on server (not in Angular source). Use nonce-based CSP with script-src 'nonce-{nonce}' and avoid unsafe-inline/unsafe-eval.
- HTTP: Use Interceptors to attach secure tokens. Use HttpOnly cookies managed by server — not localStorage or sessionStorage because they accessible via XSS.
- Secrets: Never store API keys or secrets in Angular source code or bundle.
Anti-Patterns
- No trust-marking on user input: Trust Angular's sanitization; reserve trusted HTML APIs for verified static content only.
- No localStorage for tokens: Use HttpOnly cookies via interceptors for auth tokens.
- No secrets in source: Never embed API keys or secrets in Angular bundle code.
References
- Security Best Practices
- common/security-standards
CSP and secret checklist
- Use a server-generated, per-response nonce in
script-src 'nonce-{nonce}'; do not use a static nonce. - Keep controlled provenance explicit: trust-mark only controlled and verified or vetted static CMS content.
- Do not put API keys or other secrets in the compiled bundle.
Canonical response anchors
- Additional task-grounded exact anchors: {{ content }}