Очистить ввод в Angular2

Я пытаюсь получить стороннее (потенциально небезопасное) содержимое HTML из моей базы данных и вставить его в мой документ HTML.

Как мне безопасно это сделать (Защита от XSS)?

В Angular1.x раньше было $sce чтобы дезинфицировать вход, как мне это сделать в Angular2? Насколько я понимаю, Angular2 автоматически очищает его по умолчанию, это правильно?

Как то так не получится

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

1 ответ

Решение

Чтобы вставить обычный 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">';

} 
Другие вопросы по тегам