关于angular:在Angular2中清理输入

Sanitize input in Angular2

本问题已经有最佳答案,请猛点这里访问。

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

我如何安全地做到这一点(防止XSS)?

在angular1.x中,曾经有$sce用于清除输入,如何在angular2中执行此操作?据我所知,Angular2默认自动对其进行清理,对吗?

像这样的事情是行不通的:

1
    {{someBoundValueWithSafeHTML}} // I want HTML from db here


要将普通HTML插入Angular2应用程序,可以使用[innerHtml]指令。

1
 

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

但是,如果您收到不安全的HTML警告,那么在注入之前,您应该首先信任HTML。你必须用DomSanitizer来做这样的事。例如,一个元素被认为是安全的。元素不是。

1
2
3
4
5
6
7
8
9
10
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){}
}

让你的模板保持不变:

1
 

不过,还是要注意:

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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的声明数组中:

1
2
3
4
5
6
7
8
9
@Component({
   selector: 'app',
   template: ``
})
export class AppComponent{

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

}

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@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的声明数组中添加指令:

1
2
3
4
5
6
7
8
9
@Component({
   selector: 'app',
   template: ``
})
export class AppComponent{

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

}