1.Cross-site scripting (跨站脚本)
跨站脚本(Cross-site scripting,通常简称为XSS)是一种网站应用程序的安全漏洞攻击,是代码注入的一种。它允许恶意用户将代码注入到网页上,其他用户在观看网页时就会受到影响。这类攻击通常包含了HTML以及用户端脚本语言。
XSS攻击通常指的是通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序。这些恶意网页程序通常是JavaScript,但实际上也可以包括Java,VBScript,ActiveX,Flash或者甚至是普通的HTML。攻击成功后,攻击者可能得到更高的权限(如执行一些操作)、私密网页内容、会话和cookie等各种内容。 — 维基百科
————摘自sf
2.安全风险防范
调用任何bypassSecurityTrust ... API都会禁用Angular对传入值的内置清理,也就是说只要调用了此API就会怼传入的函代码快的值进行严格的检查。包括路径,html标签,js代码等确定安全后方可以插入。而且插入方式不可以是插值法直接插入,必须是属性绑定的形式插入。
DomSanitizer有助于防止跨站点脚本安全漏洞(XSS),通过清除值以便在不同的DOM上下文中安全使用。
例如,当在一个<a href="someValue">超链接中绑定一个URL时,someValue将被清理,以便攻击者不能注入例如一个可以在网站上执行代码的javascript:URL。
在特定情况下,可能需要禁用清理,例如,如果应用程序真的需要生成一个带有动态值的javascript:style链接。用户可以绕过安全性,方法是使用bypassSecurityTrust ...方法之一构造一个值,然后绑定到模板中的值。
这些情况应该非常罕见,必须非常小心,避免造成跨站点脚本(XSS)安全漏洞!
当使用bypassSecurityTrust ...时,确保尽可能早地调用方法并尽可能接近值的来源,以便于验证它的使用是否会产生安全错误。
如果值是安全的,则不要求(并且不推荐)绕过安全性。不以可疑协议开头的URL或不包含危险代码的HTML代码段。卫生洗涤剂保持完整的安全值。
——翻译自angular官网
通俗来讲:就是Angular 2 中默认将所有输入值视为不受信任。当我们通过 property,attribute,样式,类绑定或插值等方式,将一个值从模板中插入到DOM中时,Angular 2 会自帮我们清除和转义不受信任的值。我们来看一下具体示例:
ts
import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import {DomSanitizer} from "@angular/platform-browser";
@IonicPage()
@Component({
selector: 'page-test',
templateUrl: 'test.html',
})
export class TestPage {
public htmling="<div>很高<p>使得</p><a >蓝色</a><script>goban()</script></div>";
constructor(public navCtrl: NavController, public navParams: NavParams,public dz:DomSanitizer ) {
}
ionViewDidLoad() {
}
assembleHTML(strHTML:any) {
return this.dz.bypassSecurityTrustHtml(strHTML);
}
}
html:
<ion-header>
<ion-navbar>
<ion-title>test</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<!--html 属性绑定方法-->
<div [innerHTML]="assembleHTML(htmling)"></div>
</ion-content>
结果:
结果angular拦截后当成了字符串输出,并没有执行该方法
3.用法:
3.1 bypassSecurityTrustHtml(value: string): SafeHtml
ts
import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import {DomSanitizer} from "@angular/platform-browser";
@IonicPage()
@Component({
selector: 'page-test',
templateUrl: 'test.html',
})
export class TestPage {
public htmling="<div>很高<p>使得</p><a >蓝色</a></div>";
constructor(public navCtrl: NavController, public navParams: NavParams,public dz:DomSanitizer ) {
}
ionViewDidLoad() {
console.log('ionViewDidLoad TestPage');
// html
this.aa=this.dz.bypassSecurityTrustHtml(this.htmling);=
}
assembleHTML(strHTML:any) {
return this.dz.bypassSecurityTrustHtml(strHTML);
}
}
html:
<ion-header>
<ion-navbar>
<ion-title>test</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<!--html 属性绑定方法-->
<div [innerHTML]="assembleHTML(htmling)"></div>
<!--html错误写法-->
<div>{{aa}}</div>
<!--html 属性绑定属性值-->
<div [innerHTML]="aa"></div>
</ion-content>
效果:
可以看见错误的绑定方式会使代码片段当做html显示
3.2 bypassSecurityTrustStyle
ts
import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import {DomSanitizer} from "@angular/platform-browser";
@IonicPage()
@Component({
selector: 'page-test',
templateUrl: 'test.html',
})
export class TestPage {
public htmling="height: 100px;background-color: red";
constructor(public navCtrl: NavController, public navParams: NavParams,public dz:DomSanitizer ) {
}
ionViewDidLoad() {
console.log('ionViewDidLoad TestPage');
// html
this.aa=this.dz.bypassSecurityTrustStyle(this.htmling)
}
}
html:
<ion-header>
<ion-navbar>
<ion-title>test</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<div [style]="aa"></div>
</ion-content>
效果:
3.3 bypassSecurityTrustUrl
ts
import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import {DomSanitizer} from "@angular/platform-browser";
@IonicPage()
@Component({
selector: 'page-test',
templateUrl: 'test.html',
})
export class TestPage {
public htmling="./assets/icon/1000.png";
constructor(public navCtrl: NavController, public navParams: NavParams,public dz:DomSanitizer ) {
}
ionViewDidLoad() {
console.log('ionViewDidLoad TestPage');
// html
this.aa=this.dz.bypassSecurityTrustUrl(this.htmling)
}
}
html:
<ion-header>
<ion-navbar>
<ion-title>test</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<div > <img [src]="aa"></div>
</ion-content>
效果:
3.4 bypassSecurityTrustResourceUrl
ts
import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import {DomSanitizer} from "@angular/platform-browser";
@IonicPage()
@Component({
selector: 'page-test',
templateUrl: 'test.html',
})
export class TestPage {
public htmling="https://segmentfault.com/";
public aa:object;
constructor(public navCtrl: NavController, public navParams: NavParams,public dz:DomSanitizer ) {
}
ionViewDidLoad() {
console.log('ionViewDidLoad TestPage');
// html
this.aa=this.dz.bypassSecurityTrustResourceUrl(this.htmling)
}
}
html:
<ion-header>
<ion-navbar>
<ion-title>test</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<iframe [src]="aa"></iframe>
</ion-content>
效果: