清理Angular2中的输入[重复]

Posted

技术标签:

【中文标题】清理Angular2中的输入[重复]【英文标题】:Sanitize input in Angular2 [duplicate] 【发布时间】:2016-03-31 17:41:48 【问题描述】:

我正在尝试从我的数据库中获取第三方(可能不安全)的 html 内容并将其插入到我的 html 文档中。

我如何安全地做到这一点(防止 XSS)?

Angular1.x 中曾经有 $sce 来清理输入,我该如何在 Angular2 中做到这一点?据我了解,默认情况下 Angular2 会自动对其进行清理,对吗?

这样的事情是行不通的:

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

【问题讨论】:

@DanielGartmann 我确实确实想清理内容。既然您指出了这一点,我对自己的措辞感到惊讶,我将编辑我的问题。谢谢。 Angular 会自动清理内容。来自angular.io/guide/security 的防止跨站点脚本部分:为了系统地阻止 XSS 错误,Angular默认情况下将所有值视为不受信任。当一个值通过属性、属性、样式、类绑定或插值从模板插入到 DOM 中时,Angular 会清理和转义不受信任的值。 【参考方案1】:

要将普通 HTML 插入到您的 angular2 应用程序中,您可以使用 [innerHtml] 指令。

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

这不适用于具有自己的组件和指令的 HTML,至少不是您期望的那样。

但是,如果您确实收到了不安全的 html 警告,您应该在注入之前首先信任 HTML。你必须使用DomSanitizer 来做这样的事情。例如,&lt;h3&gt; 元素被认为是安全的。 &lt;input&gt; 元素不是。

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">';

 

【讨论】:

天哪,我试过inner-html。太糟糕了...谢谢! 自.. alpha.51 以来,规格发生了变化,如果我是正确的。 CamelCase 现在无处不在(除了元素标签)。欢迎你:) 我从来没有使用过任何 alpha 版本,马上就进入了 beta,但是,我想我在研究时从一些早期的 alpha 版本中发现了inner-html 请参阅我们需要使用DomSanitizer 的最新文档,如angular.io/docs/ts/latest/api/platform-browser/index/… 所示。已经进行了一些重命名。 @JonathanReyes 感谢您的提醒。更新了我的答案

以上是关于清理Angular2中的输入[重复]的主要内容,如果未能解决你的问题,请参考以下文章

模板中的Angular 2重复组件引用另一个元素

使用angular2将HTML从服务器插入DOM(Angular2中的一般DOM操作)[重复]

如何在Angular2中的组件之间共享数据[重复]

模型绑定不适用于angular2中的选择[重复]

Angular2:表格中的诊断属性是啥

Angular2 从 JSON 数组中删除重复项