Очистить ввод в 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">';
}