清理 Angular2 中的输入

Sanitize input in Angular2

我正在尝试从我的数据库中获取第三方(可能不安全)html 内容并将其插入到我的 html 文档中。

我如何安全地做到这一点(针对 XSS 的保护)?

Angular1.x中曾经有$sce来清理输入,我如何在Angular2[=23=中做到这一点] ?据我了解,Angular2 默认情况下会自动清理它,对吗?

像这样的东西是行不通的:

<div class="foo">
    {{someBoundValueWithSafeHTML}} // I want HTML from db here
</div>

要将普通 HTML 插入到您的 angular2 应用程序中,您可以使用 [innerHtml] 指令。

<div [innerHtml]="htmlProperty"></div>

这不适用于 HTML,它有自己的组件和指令,至少不是您期望的那样。

但是,如果您收到不安全的 html 警告,您应该在注入之前首先信任 HTML。你必须使用 DomSanitizer 来做这样的事情。例如,<h3> 元素被认为是安全的。 <input> 元素不是。

export class AppComponent  {

    private _htmlProperty: string = '<input type="text" name="name">';

    public get htmlProperty() : SafeHtml {
       return this.sr.bypassSecurityTrustHtml(this._htmlProperty);
    }

    constructor(private sr: DomSanitizer){}
}

并让您的模板保持不变:

<div [innerHtml]="htmlProperty"></div>

不过要提个醒:

WARNING: calling this method with untrusted user data exposes your application to XSS security risks!

如果你打算更多地使用这个技巧,你可以尝试写一个@Pipe来完成这个任务。

import { Pipe, PipeTransform } from '@angular/core';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';

@Pipe({
    name: 'trustHtml'
})
export class TrustHtmlPipe implements PipeTransform  {    
   constructor(readonly sr: DomSanitizer){}  

   transform(html: string) : SafeHtml {
      return this.sr.bypassSecurityTrustHtml(html); 
   } 
} 

如果你有这样的烟斗,你的 AppComponent 会变成这样。不要忘记将管道添加到 NgModule:

的声明数组中
@Component({
   selector: 'app',
   template: `<div [innerHtml]="htmlProperty | trustHtml"></div>`
})
export class AppComponent{

    public htmlProperty: string = '<input type="text" name="name">';

} 

或者你可以写一个@Directive来做同样的事情:

@Directive({
   selector: '[trustHtml]'
})
export class SanitizeHtmlDirective {

    @Input()
    public set trustHtml(trustHtml: string) {
      if (this._trustHtml !== trustHtml) {
        this._trustHtml = trustHtml;
        this.innerHtml = this.sr.bypassSecurityTrustHtml(this.trustHtml);
      }
    }

    @HostBinding('innerHtml')
    innerHtml?: SafeHtml;

    private _trustHtml: string;

    constructor(readonly sr: DomSanitizer){}
}

如果您有这样的指令,您的 AppComponent 会变成这样。不要忘记将指令添加到 NgModule:

的声明数组中
@Component({
   selector: 'app',
   template: `<div [trustHtml]="htmlProperty"></div>`
})
export class AppComponent{

    public htmlProperty: string = '<input type="text" name="name">';

}