清理Angular2中的输入

时间:2015-12-25 22:34:28

标签: angular typescript sanitize

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

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

Angular1.x 中曾经有$sce来清理输入,我该如何在 Angular2 中执行此操作?据我了解, Angular2 默认会自动清理它,这是正确的吗?

这样的东西不起作用:

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

1 个答案:

答案 0 :(得分:39)

要将普通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._sanitizer.bypassSecurityTrustHtml(this._htmlProperty);
    }

    constructor(private _sanitizer: DomSanitizer){}
}

让你的模板与此保持一致:

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

虽然有点提醒:

  

警告:使用不受信任的用户数据调用此方法会使您的应用程序面临XSS安全风险!

如果您打算更多地使用此技术,可以尝试编写@Pipe来完成此任务。

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

@Pipe({
    name: 'sanitizeHtml'
})
export class SanitizeHtmlPipe implements PipeTransform  {

   constructor(private _sanitizer: DomSanitizer){}  

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

如果您有这样的管道,您的AppComponent将更改为此。不要忘记将管道添加到NgModule

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

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

} 

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

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

    @Input()
    public sanitizeHtml: string;   

    @HostBinding('innerHtml')
    public get innerHtml(): SafeHtml {
        return this._sanitizer.bypassSecurityTrustHtml(this.sanitizeHtml);
    }

    constructor(private _sanitizer: DomSanitizer){}
}

如果您有这样的指令,您的AppComponent将更改为此。不要忘记将指令添加到NgModule

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

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

}