Angular 2 DomSanitizer

Cross-site scripting (跨站脚本)

跨站脚本Cross-site scripting,通常简称为XSS)是一种网站应用程序的安全漏洞攻击,是代码注入的一种。它允许恶意用户将代码注入到网页上,其他用户在观看网页时就会受到影响。这类攻击通常包含了HTML以及用户端脚本语言。

XSS攻击通常指的是通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序。这些恶意网页程序通常是JavaScript,但实际上也可以包括Java,VBScript,ActiveX,Flash或者甚至是普通的HTML。攻击成功后,攻击者可能得到更高的权限(如执行一些操作)、私密网页内容、会话和cookie等各种内容。 — 维基百科

Cross-site scripting 示例

互联网上的几乎每个博客都有一个评论的系统,允许用户对文章发表评论。评论信息一般使用常用的 HTML 表单进行提交。具体示例如下:

Comments

    var $form = $('form'); var $comment = $('.comment'); var $ul = $('ul'); $form.on('submit', e => { e.preventDefault(); var value = $($comment).val(); if(value) { $($ul).append(`
  • ${value}
  • `); } });

    现在假设攻击者将以下代码作为评论信息发送到服务器:

    如果网站没有保护自己免受跨站脚本的攻击,该内容将被保存到数据库中,访问该页面的所有用户将重定向到攻击者的URL。然而现实中一个真正的攻击者会创建一个更危险的脚本,例如,攻击者可以记录键盘事件并将这些信息发送到他自己拥有的服务器。

    刚才我们看到的,只是 XSS 攻击的一个简单示例,它还可以有许多形式,如URL查询,href属性,CSS等等...

    如果你想了解更多关于XSS的信息,可以浏览这个网站 - excess-xss。

    Angular 2 如何保护我们免受 XSS 攻击

    Angular 2 中默认将所有输入值视为不受信任。当我们通过 property,attribute,样式,类绑定或插值等方式,将一个值从模板中插入到DOM中时,Angular 2 会自帮我们清除和转义不受信任的值。我们来看一下具体示例:

    import { Component } from '@angular/core';
    
    @Component({
      selector: 'exe-app',
      template: `
       
    ` }) export class AppComponent { html: string; constructor() { this.html = "

    DomSanitizer

    "; } }

    以上代码运行后浏览器显示的结果:

    从上图可以看出,Angular 2 在编译的时候,会自动清理 HTML 输入并转义不安全的代码,因此在这种情况下,脚本不会运行,只能在屏幕上显示为文本。接下来我们继续来看一个例子,如何绑定 iframe 的 src 属性值:

    import { Component } from '@angular/core';
    
    @Component({
      selector: 'exe-app',
      template: `
        
      `
    })
    export class AppComponent {
      iframe: string;
      constructor() {
        this.iframe = "https://segmentfault.com/";       
      }
    }

    以上代码运行后,在浏览器中无法正常显示内容,控制台中输出了以下异常信息:

    EXCEPTION: Error in ./AppComponent class AppComponent - inline template:1:12 caused by: unsafe value used in a resource URL context (see http://g.co/ng/security#xss)

    Angular 抛出此错误是因为 iframe 的 src 属性是资源 URL 安全上下文,因为不可信源可以在用户不知情的情况下执行某些不安全的操作。但如果我们确认资源的 URL 是安全的,要怎么告知 Angular 该 URL 地址是安全的,给我们通行证呢 ?答案是,我们可以使用 Angular 2 中提供的 DomSanitizer 服务,具体示例如下:

    import { Component } from '@angular/core';
    import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser'
    
    @Component({
      selector: 'exe-app',
      template: `
        
      `
    })
    export class AppComponent {
      iframe: SafeResourceUrl;
      
      constructor(private sanitizer: DomSanitizer) {
        this.iframe = this.sanitizer.bypassSecurityTrustResourceUrl(
          "https://segmentfault.com/");       
      }
    }

    以上代码运行后,在浏览器中我们就可以看到正常的内容。另外需要注意的是,如果不受信任的用户数据调用这些方法,我们的应用程序将会存在 XSS 安全风险。

    DomSanitizer - sanitize() 方法

    有时后我们需要手动过滤输入值,这时你可以使用 sanitize 方法,它的签名如下:

    abstract sanitize(context: SecurityContext, value: any): string;

    该方法的第一个参数表示 SecurityContext (安全上下文),它的可选值如下:

    • None

    • HTML

    • STYLE

    • SCRIPT

    • URL

    • RESOURCE_URL

    sanitize 方法的使用示例如下:

    import { Component, SecurityContext } from '@angular/core';
    import { DomSanitizer } from '@angular/platform-browser'
    
    @Component({
      selector: 'exe-app',
      template: `
       
    ` }) export class AppComponent { html: string; constructor(private sanitizer: DomSanitizer) { this.html = this.sanitizer.sanitize(SecurityContext.HTML, "

    Sanitize

    "); console.log(this.html); } }

    以上代码运行后,控制台的输出信息:

    WARNING: sanitizing HTML stripped some content (see http://g.co/ng/security#xss).
    app.component.ts:15 

    Sanitize

    attackerCode()

    自定义 keepHtml 指令

    keepHtml 指令定义

    import { Pipe, PipeTransform } from '@angular/core';
    import { DomSanitizer } from '@angular/platform-browser';
    
    @Pipe({ name: 'keepHtml', pure: false })
    export class EscapeHtmlPipe implements PipeTransform {
      constructor(private sanitizer: DomSanitizer) {
      }
    
      transform(content) {
        return this.sanitizer.bypassSecurityTrustHtml(content);
      }
    }

    keepHtml 指令使用

    参考资源

    • Angular 2 Security - The DomSanitizer Service

    你可能感兴趣的:(typescript,angular2,angular.js)