使用AngularJS中的SCE来防止XSS攻击的方法


Posted in Javascript onJune 18, 2015

这篇文章展示了有关XSS(跨站脚本)的不同方案以及怎样使用AngularJS中SCE($sceProvider),sanitize service这些特性来正确处理XSS。如果我遗漏了什么重要的地方请直接评论/建议。同时,错别字请见谅。

以下几点内容将是我接下来要讲述的重点:

  •     全部转码HTML
  •     安全插入HTML的同时忽略类似“script"这样的标签。如果不加以注意,这将一样存在风险同时也会丑化页面,尤其是在有”img“标签的时候。
  •     依赖并插入纯HTML;这也有风险的同时会让网页很难看。

使用ng-bind指令转码HTML

你可以用ng-bind指令来转码整个网页。它将会转码所有HTML标签但是仍然显示本来的样子。下列代码显示了ng-bind的用法。 

<div>
<form>
  <h1>AngularJS XSS Demo Test</h1>
  <hr/>
  <div class="col-md-12">
  <input type="text" ng-model="name" class="form-control col-md-12" ng-change="processHtmlCode()" placeholder="Enter Some HTML Text..."/>
  </div>
</form>
</div>
<hr/>
<div style="padding:20px">
  <span><strong>ng-bind directive: Note that HTML text is entered as it is.</strong></span><br/>
  <span ng-bind="helloMessage">{{helloMessage}}</span>
</div>

下面的图证明了以上言论。注意在输入栏中的HTML代码。它和在HTML页面中完全一样。

使用AngularJS中的SCE来防止XSS攻击的方法

使用安全的方式插入HTML,也可以使用 ng-bind-html 指令忽略掉诸如“script”这样的元素

这是解决XSS攻击的关键. 也就是说,你仍然应该关注诸如“img"这样的元素 ( 作为一部分包含进了白名单中; 还有空元素) 因为它恩能够在你的web页面上展示任何图片 (包括非法的那些), 因此,它也可能会给你的web页面带来不利影响. 使用 ng-bind-html 指令皆可以AngularJS诸如“script”这样的JavaScript标记直接被忽略掉. ng-bind-html 指令会计算表达式,并且用一种安全的方式将结果HTML插入元素中. 对于用户会输入包含了HTML内容(比如在评论中)的情况,放到 ng-bind-html指令中可以确保文本被编码为白名单中的安全HTML字符. 安全字符的白名单被作为 $sanitize 的一部分编码,下面会讲到. 下面这些都被包含进了安全列表中 (直接从源代码中获得):

    空元素:

area,br,col,hr,img,wbr.
详细信息请访问 http://dev.w3.org/html5/spec/Overview.html#void-elements

    块元素:

address,article,aside,blockquote,caption,center,del,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5,h6,header,hgroup,hr,ins,map,menu,nav,ol,pre,script,section,table,ul

    内联元素:

a,abbr,acronym,b,bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,q,ruby,rp,rt,s,samp,small,span,strike,strong,sub,sup,time,tt,u,var

    结尾标记元素:

colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr,rp,rt.
详细信息请访问 http://dev.w3.org/html5/spec/Overview.html#optional-tags

下面的这两个元素 因为其内容不收信任,需要被规避掉. 在这种情况下,如果你想要展示它们,就要使用 $sce 服务,调用Angular 的 trustAsHtml 方法来执行下面提到的元素.

  •     script
  •     style

如下呈现的代码展示了 ng-bind-html 指令的使用.
 

<div>
<form>
  <h1>AngularJS XSS Demo Test</h1>
  <hr/>
  <div class="col-md-12">
  <input type="text" ng-model="name" class="form-control col-md-12" ng-change="processHtmlCode()" placeholder="Enter Some HTML Text..."/>
  </div>
</form>
</div>
<hr/>
<div style="padding:20px">
  <span>ng-bind-html directive: Note that image is displayed appropriately as a result of text entered in the text field.</span>
  <span ng-bind-html="helloMessage"></span>
</div>

下面这张图片展示了当在文本域中输入HTML代码,Angular用一种安全的方式插入到DOM时,是什么样子的. 注意 “img” 元素是上述列表中空元素的一份子. 因为代码被输入到了文本域中,作为”img"出现的图片被放到了受信任的列表(白名单)中。

使用AngularJS中的SCE来防止XSS攻击的方法

信任并插入整段HTML

警告: 这很危险,并且可能很容易就最终造成你web站点的污染. 只有当你知道并且充分确认时,你才应该使用 trustAsHtml. 如此,你就有充足的信心认为这段文本是可以被信任的, 你应该使用$sce 服务并且调用 trustAsHtml 方法来讲整段HTML插入DOM中。在$sce服务被用来调用 trustAsHtml 方法来信任一段HTML代码时,请留意HTML和其中的JavaScript代码块. 在这种情况下,一段诸如 “<style>.hello{color:red}</style>” 这样的代码被插入了,它最后可能会也给现有的HTML元素加上样式。这可能不是很好。人们也可能采用那种方式用非法的图片替换背景图片.
 

<script type="text/javascript">
  angular.module('HelloApp', ["ngSanitize"])
  .controller('HelloCtrl', ['$scope', '$sce', function($scope, $sce){
    $scope.name="";
    $scope.processHtmlCode  =  function() {
      $scope.helloMessage = "<h1>" + $scope.name + "</h1>";  
      $scope.trustedMessage = $sce.trustAsHtml( $scope.name );
    }
  }])
 
  </script>
<!-- Pay attention to class hello which is coded in UI and as a result, element is painted in red-->
<div style="padding:20px">
    <span class="hello"><strong>ng-bind directive: Note that HTML text is entered as it is.</strong></span><br/>
    <span class="hello" ng-bind="helloMessage">{{helloMessage}}</span>
</div>
<hr/>
<div style="padding:20px">
    <span>Note that script tag is executed as well.</span>
    <span ng-bind-html="trustedMessage"></span>
</div>

下面的图片展示了当在文本域中输入将要被插入DOM中的HTML样式代码时,会是什么样子. 这里的结果就是, 其它的HTML元素也带上了红色, 如下所示. 在某些场景中,黑客可能会插入一段带有背景样式越苏,这可能会显示出原本不要被显示的背景,给最终用户带来糟糕的体验.

使用AngularJS中的SCE来防止XSS攻击的方法 

<html>
<head>
  <title>Hello AngularJS</title>
  <link rel="stylesheet" type="text/css" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
  <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.3/angular.min.js"></script>
  <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.3/angular-sanitize.min.js"></script>
</head>
<body class="container" ng-app="HelloApp" ng-controller="HelloCtrl">
  <div>
    <form>
      <h1>AngularJS XSS Demo Test</h1>
      <hr/>
      <div class="col-md-12">
        <input type="text" ng-model="name" class="form-control col-md-12" ng-change="processHtmlCode()" placeholder="Enter Some HTML Text..."/>
      </div>
    </form>
    <hr/>
  </div>
  <hr/>
  <div style="padding:20px">
    <span class="hello"><strong>ng-bind directive: Note that HTML text is entered as it is.</strong></span><br/>
    <span class="hello" ng-bind="helloMessage">{{helloMessage}}</span>
  </div>
  <hr/>
  <div style="padding:20px">
    <span>Note that script tag is executed as well.</span>
    <span ng-bind-html="trustedMessage"></span>
  </div>
  <hr/>
  <div style="padding:20px">
    <span>ng-bind-html directive: Note that image is displayed appropriately as a result of text entered in the text field.</span>
    <span ng-bind-html="helloMessage"></span>
  </div>
  <hr/>
  <script type="text/javascript">
  angular.module('HelloApp', ["ngSanitize"])
  .controller('HelloCtrl', ['$scope', '$sce', function($scope, $sce){
    $scope.name="";
    $scope.processHtmlCode  =  function() {
      $scope.helloMessage = "<h1>" + $scope.name + "</h1>";  
      $scope.trustedMessage = $sce.trustAsHtml( $scope.name );
    }
  }])
 
  </script>
</body>
</html>
Javascript 相关文章推荐
javascript 二维数组的实现与应用
Mar 16 Javascript
jQuery ajax(复习)—Baidu ajax request分离版
Jan 24 Javascript
jquery实现的下拉和收缩效果示例
Aug 21 Javascript
JavaScript中的setMilliseconds()方法使用详解
Jun 11 Javascript
JavaScript运动减速效果实例分析
Aug 04 Javascript
基于javascript实现漂亮的页面过渡动画效果附源码下载
Oct 26 Javascript
js实现div模拟模态对话框展现URL内容
May 27 Javascript
javascript简单实现等比例缩小图片的方法
Jul 27 Javascript
微信小程序 教程之WXSS
Oct 18 Javascript
Bootstrap源码解读按钮(5)
Dec 23 Javascript
JS实现根据密码长度显示安全条功能
Mar 08 Javascript
js Dom实现换肤效果
Oct 21 Javascript
初步认识JavaScript函数库jQuery
Jun 18 #Javascript
用JavaScript显示浏览器客户端信息的超相近教程
Jun 18 #Javascript
浅谈Jquery核心函数
Jun 18 #Javascript
$.extend 的一个小问题
Jun 18 #Javascript
纯js实现无限空间大小的本地存储
Jun 18 #Javascript
JS实现当前页居中分页效果的方法
Jun 18 #Javascript
javascript中Date()函数在各浏览器中的显示效果
Jun 18 #Javascript
You might like
php基于curl重写file_get_contents函数实例
2016/11/08 PHP
CI框架简单分页类用法示例
2020/06/06 PHP
用jQuery扩展自写的 UI导航
2010/01/13 Javascript
JavaScript 计算图片加载数量的代码
2011/01/01 Javascript
setTimeout的延时为0时多个浏览器的区别
2012/05/23 Javascript
JS获取下拉列表所选中的TEXT和Value的实现代码
2014/01/11 Javascript
JavaScript判断IE版本型号
2015/07/27 Javascript
简单讲解AngularJS的Routing路由的定义与使用
2016/03/05 Javascript
使用Node.js实现简易MVC框架的方法
2017/08/07 Javascript
微信小程序实现验证码获取倒计时效果
2018/02/08 Javascript
微信小程序6位或多位验证码密码输入框功能的实现代码
2018/05/29 Javascript
layui type2 通过url给iframe子页面传值的例子
2019/09/06 Javascript
Vue中常用rules校验规则(实例代码)
2019/11/14 Javascript
JavaScript实现简易聊天对话框(加滚动条)
2020/02/10 Javascript
Node Express用法详解【安装、使用、路由、中间件、模板引擎等】
2020/05/13 Javascript
Python操作MongoDB数据库PyMongo库使用方法
2015/04/27 Python
python中函数总结之装饰器闭包详解
2016/06/12 Python
python3的输入方式及多组输入方法
2018/10/17 Python
浅析Python语言自带的数据结构有哪些
2019/08/27 Python
Selenium常见异常解析及解决方案示范
2020/04/10 Python
Python求凸包及多边形面积教程
2020/04/12 Python
Django基于Models定制Admin后台实现过程解析
2020/11/11 Python
CSS3动画特效在活动页中的应用
2020/01/21 HTML / CSS
Aveda美国官网:天然护发产品、洗发水、护发素和沙龙
2016/12/09 全球购物
加拿大在线眼镜零售商:SmartBuyGlasses加拿大
2019/05/25 全球购物
工商管理实习自我鉴定
2013/09/28 职场文书
模具毕业生推荐信
2014/02/15 职场文书
行政内勤岗位职责
2014/04/07 职场文书
奥巴马开学演讲稿
2014/05/15 职场文书
另类冲刺标语
2014/06/24 职场文书
幼儿园欢迎词范文
2015/01/26 职场文书
河童之夏观后感
2015/06/11 职场文书
毕业证明模板
2015/06/19 职场文书
家庭教育培训学习心得体会
2016/01/14 职场文书
礼仪培训心得体会
2016/01/22 职场文书
JavaScript实现队列结构过程
2021/12/06 Javascript