Sanitize input in Angular2 [duplicate]

半世苍凉 提交于 2019-12-17 09:35:47

问题


I am trying to get third-party (potentially unsafe) html content from my database and insert it into my html document.

How do I safely do that (Protection against XSS) ?

In Angular1.x there used to be $sce to sanitize input, how do I do that in Angular2 ? As far as I understand, Angular2 automatically sanitizes it by default, is that correct ?

Something like this will not work:

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

回答1:


To insert normal HTML into your angular2 app, you can use the [innerHtml] directive.

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

This is not going to work with HTML which has its own components and directives, at least not in the way you'd expect it.

If however you do get an unsafe html warning you should trust the HTML first before injecting it. You have to use the DomSanitizer for such a thing. For instance, an <h3> element is considered safe. An <input> element is not.

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){}
}

And have your template stay the same as this:

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

A little heads-up though:

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

If you plan on using this technique more, you can try to write a @Pipe to fulfill this task.

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); 
   } 
} 

If you have a pipe like this, your AppComponent will change to this. Don't forget to add the pipe to your declarations array of your NgModule:

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

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

} 

Or you can write a @Directive to do the same:

@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(readonlysr: DomSanitizer){}
}

If you have a directive like this, your AppComponent will change to this. Don't forget to add the directive to your declarations array of your NgModule:

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

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

} 


来源:https://stackoverflow.com/questions/34467000/sanitize-input-in-angular2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!