web-dev-qa-db-ja.com

Angular2での入力のサニタイズ

データベースからサードパーティの(潜在的に安全でない)htmlコンテンツを取得し、それをhtmlドキュメントに挿入しようとしています。

それを安全に行うにはどうすればよいですか(XSSに対する保護)?

Angular1.xでは、以前は$sce入力をサニタイズするには、Angular2でどのようにすればよいですか?私が理解する限り、Angular2はデフォルトで自動的にサニタイズしますが、それは正しいですか?

このようなものは機能しません:

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

Angular2アプリに通常のHTMLを挿入するには、[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(readonlysr: DomSanitizer){}
}

このようなディレクティブがある場合、AppComponentはこれに変更されます。 NgModuleの宣言配列にディレクティブを追加することを忘れないでください:

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

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

} 
42
PierreDuc