Angular15用innerHTML+DomSanitizer遭Veracode报XSS漏洞的修复咨询
我在Angular 15项目中通过API获取HTML响应并渲染,代码如下:
HTML代码
<div [innerHTML]="htmlResponse | safe: 'html'"></div>
TypeScript代码(SafePipe)
import { Pipe, PipeTransform } from '@angular/core'; import { DomSanitizer, SafeHtml, SafeStyle, SafeScript, SafeUrl, SafeResourceUrl } from '@angular/platform-browser'; @Pipe({ name: 'safe' }) export class SafePipe implements PipeTransform { constructor(protected sanitizer: DomSanitizer) {} public transform(value: any, type: string): SafeHtml | SafeStyle | SafeScript | SafeUrl | SafeResourceUrl { switch (type) { case 'html': return this.sanitizer.bypassSecurityTrustHtml(value); case 'style': return this.sanitizer.bypassSecurityTrustStyle(value); case 'script': return this.sanitizer.bypassSecurityTrustScript(value); case 'url': return this.sanitizer.bypassSecurityTrustUrl(value); case 'resourceUrl': return this.sanitizer.bypassSecurityTrustResourceUrl(value); default: throw new Error(`Invalid safe type specified: ${type}`); } } }
但Veracode检测出漏洞:
Improper Neutralization of Script-Related HTML Tags in a Web Page (Basic XSS)
漏洞原因
你使用bypassSecurityTrustHtml完全绕过了Angular的内置HTML清理机制,相当于强制Angular信任所有外部传入的HTML内容。如果API返回的HTML包含恶意脚本(比如<script>标签、onclick这类事件属性、javascript:伪协议链接),会直接在页面执行,触发XSS攻击,这也是Veracode标记该漏洞的原因。
修复方案
方案1:使用Angular自动清理(推荐)
如果不需要渲染Angular默认判定为危险的标签/属性,直接移除safe: 'html'管道即可。Angular会自动过滤所有危险内容,只保留安全的HTML标签和属性:
<div [innerHTML]="htmlResponse"></div>
默认过滤规则包括:移除<script>、<iframe>(除非额外配置)、所有on*事件属性、javascript:开头的链接等。
方案2:自定义清理规则(需保留特定危险内容时)
如果必须渲染某些Angular默认过滤的内容(比如可信域名的iframe、自定义事件),不要直接全量信任,先通过Angular的sanitize方法做基础清理,再手动允许特定内容:
修改SafePipe的html分支逻辑:
import { SecurityContext } from '@angular/core'; // ... case 'html': // 先执行默认清理,过滤绝大多数危险内容 const sanitizedHtml = this.sanitizer.sanitize(SecurityContext.HTML, value); // 按需添加自定义规则,比如允许特定域名的iframe const trustedHtml = sanitizedHtml.replace( /<iframe src="(https:\/\/your-trusted-domain\.com.*?)"/g, '<iframe src="$1" allow="fullscreen"' ); return this.sanitizer.bypassSecurityTrustHtml(trustedHtml);
注意:此方案仅适用于你能完全控制API返回内容,或能精准过滤危险代码的场景。
方案3:用第三方库做严格净化(来源不可信时)
如果API返回的HTML来源不可控,推荐使用专门的HTML净化库(如DOMPurify)做前置处理:
- 安装依赖:
npm install dompurify @types/dompurify
- 修改
SafePipe:
import DOMPurify from 'dompurify'; // ... case 'html': // 用DOMPurify做严格净化,过滤所有已知XSS攻击向量 const purifiedHtml = DOMPurify.sanitize(value); return this.sanitizer.bypassSecurityTrustHtml(purifiedHtml);
DOMPurify的净化规则比Angular内置机制更全面,能覆盖更多边缘场景的攻击。
内容的提问来源于stack exchange,提问作者Jake

