angular-security

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Angular Security

Angular安全

Version: Angular 21 (2025) Tags: Security, XSS, CSRF, CSP, Sanitization
版本: Angular 21 (2025) 标签: 安全, XSS, CSRF, CSP, 内容清理

API Changes

API变更

This section documents recent version-specific API changes.
  • NEW: Trusted Types — Angular supports Trusted Types for CSP
  • NEW: HttpClient CSRF — Built-in CSRF protection with CookieXSRFStrategy
  • NEW: provideZoneChangeDetection with untrustedEvents — Zone.js event filtering
  • NEW: afterNextRender security — Run code safely after rendering
本部分记录了近期版本专属的API变动。
  • 新增:Trusted Types — Angular支持适配CSP的Trusted Types
  • 新增:HttpClient CSRF — 基于CookieXSRFStrategy的内置CSRF防护
  • 新增:搭载untrustedEvents的provideZoneChangeDetection — Zone.js事件过滤能力
  • 新增:afterNextRender安全特性 — 渲染完成后安全执行代码

Best Practices

最佳实践

  • Use DomSanitizer for safe HTML
ts
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';

constructor(private sanitizer: DomSanitizer) {}

getSafeHtml(html: string): SafeHtml {
  return this.sanitizer.bypassSecurityTrustHtml(html);
}
  • Use bypassSecurityTrust methods carefully
ts
// Only use when content is trusted
this.safeUrl = this.sanitizer.bypassSecurityTrustUrl(userInput);
this.safeScript = this.sanitizer.bypassSecurityTrustScript(script);
this.safeStyle = this.sanitizer.bypassSecurityTrustStyle(style);
this.safeResourceUrl = this.sanitizer.bypassSecurityTrustResourceUrl(url);
  • Use HttpClient with CSRF protection
ts
// Automatically uses XSRF-TOKEN cookie
http.get('/api/data').subscribe();

// Configure CSRF
provideHttpClient(
  withXsrfConfiguration({
    cookieName: 'XSRF-TOKEN',
    headerName: 'X-XSRF-TOKEN'
  })
)
  • Use innerHTML with sanitization
ts
@Component({
  template: `<div [innerHTML]="safeContent"></div>`
})
export class MyComponent {
  // Angular sanitizes automatically
  safeContent = '<p>Safe content</p>';
}
  • Avoid dynamic template evaluation
ts
// ❌ Dangerous
eval(userInput);

// ✅ Safe - use Angular's binding
{{ userInput }}
  • Use Content Security Policy
html
<meta http-equiv="Content-Security-Policy" 
      content="default-src 'self'; script-src 'self'">
  • Use Trusted Types
ts
import { provideTrustedTypes } from '@angular/core';

export const appConfig: ApplicationConfig = {
  providers: [
    provideTrustedTypes()
  ]
};
  • Validate user input
ts
import { Pipe, PipeTransform } from '@angular/core';

@Pipe({ name: 'escapeHtml' })
export class EscapeHtmlPipe implements PipeTransform {
  transform(value: string): string {
    return value
      .replace(/&/g, '&amp;')
      .replace(/</g, '&lt;')
      .replace(/>/g, '&gt;')
      .replace(/"/g, '&quot;');
  }
}
  • Use HttpClient interceptors for auth
ts
export const authInterceptor: HttpInterceptorFn = (req, next) => {
  const token = inject(AuthService).getToken();
  
  if (token) {
    const authReq = req.clone({
      setHeaders: { Authorization: `Bearer ${token}` }
    });
    return next(authReq);
  }
  return next(req);
};
  • Use router guards for route protection
ts
export const authGuard: CanActivateFn = () => {
  const auth = inject(AuthService);
  const router = inject(Router);
  
  if (auth.isAuthenticated()) {
    return true;
  }
  return router.createUrlTree(['/login']);
};
  • 使用DomSanitizer处理安全HTML
ts
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';

constructor(private sanitizer: DomSanitizer) {}

getSafeHtml(html: string): SafeHtml {
  return this.sanitizer.bypassSecurityTrustHtml(html);
}
  • 谨慎使用bypassSecurityTrust系列方法
ts
// 仅在内容可信任时使用
this.safeUrl = this.sanitizer.bypassSecurityTrustUrl(userInput);
this.safeScript = this.sanitizer.bypassSecurityTrustScript(script);
this.safeStyle = this.sanitizer.bypassSecurityTrustStyle(style);
this.safeResourceUrl = this.sanitizer.bypassSecurityTrustResourceUrl(url);
  • 配合CSRF防护使用HttpClient
ts
// 自动使用XSRF-TOKEN cookie
http.get('/api/data').subscribe();

// 配置CSRF
provideHttpClient(
  withXsrfConfiguration({
    cookieName: 'XSRF-TOKEN',
    headerName: 'X-XSRF-TOKEN'
  })
)
  • 搭配内容清理使用innerHTML
ts
@Component({
  template: `<div [innerHTML]="safeContent"></div>`
})
export class MyComponent {
  // Angular会自动执行内容清理
  safeContent = '<p>安全内容</p>';
}
  • 避免动态模板求值
ts
// ❌ 危险操作
eval(userInput);

// ✅ 安全方案 - 使用Angular的绑定语法
{{ userInput }}
  • 使用内容安全策略
html
<meta http-equiv="Content-Security-Policy" 
      content="default-src 'self'; script-src 'self'">
  • 使用Trusted Types
ts
import { provideTrustedTypes } from '@angular/core';

export const appConfig: ApplicationConfig = {
  providers: [
    provideTrustedTypes()
  ]
};
  • 校验用户输入
ts
import { Pipe, PipeTransform } from '@angular/core';

@Pipe({ name: 'escapeHtml' })
export class EscapeHtmlPipe implements PipeTransform {
  transform(value: string): string {
    return value
      .replace(/&/g, '&amp;')
      .replace(/</g, '&lt;')
      .replace(/>/g, '&gt;')
      .replace(/"/g, '&quot;');
  }
}
  • 使用HttpClient拦截器实现身份验证
ts
export const authInterceptor: HttpInterceptorFn = (req, next) => {
  const token = inject(AuthService).getToken();
  
  if (token) {
    const authReq = req.clone({
      setHeaders: { Authorization: `Bearer ${token}` }
    });
    return next(authReq);
  }
  return next(req);
};
  • 使用路由守卫保护路由
ts
export const authGuard: CanActivateFn = () => {
  const auth = inject(AuthService);
  const router = inject(Router);
  
  if (auth.isAuthenticated()) {
    return true;
  }
  return router.createUrlTree(['/login']);
};