我试图从数据库中获取第三方(可能不安全)html内容,并将其插入html文档.
我如何安全地做到这一点(防止XSS)?
在Angular1.x中,曾经有$sce
个用于消毒输入,在Angular2中,我该怎么做?据我所知,Angular2在默认情况下会自动对其进行消毒,对吗?
这样的事情是行不通的:
<div class="foo">
{{someBoundValueWithSafeHTML}} // I want HTML from db here
</div>
我试图从数据库中获取第三方(可能不安全)html内容,并将其插入html文档.
我如何安全地做到这一点(防止XSS)?
在Angular1.x中,曾经有$sce
个用于消毒输入,在Angular2中,我该怎么做?据我所知,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>
不过要注意一点:
警告:使用不受信任的用户数据调用此方法会使您的应用程序面临XSS安全风险!
如果你打算更多地使用这种技术,你可以试着写一个@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">';
}