首頁 > web前端 > js教程 > 主體

使用AngularJS中的SCE來防止XSS攻擊的方法_AngularJS

WBOY
發布: 2016-05-16 15:54:21
原創
1900 人瀏覽過

這篇文章展示了有關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頁面中完全一樣。

2015618103137625.png (1024×197)

使用安全的方式插入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,brcol,,,hr,img,br.
詳細資訊請上http://dev.w3.org/html5/spec/Overview.html#void-elements

    區塊元素:

複製程式碼 程式碼如下:
address,article,aside,b. 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,accronymb,bdi, ,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,,body,pdd,body,8,body ,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"出现的图片被放到了受信任的列表(白名单)中。

2015618103202003.png (1024×462)

信任并插入整段HTML

警告: 这很危险,并且可能很容易就最终造成你web站点的污染. 只有当你知道并且充分确认时,你才应该使用 trustAsHtml. 如此,你就有充足的信心认为这段文本是可以被信任的, 你应该使用$sce 服务并且调用 trustAsHtml 方法来讲整段HTML插入DOM中。在$sce服务被用来调用 trustAsHtml 方法来信任一段HTML代码时,请留意HTML和其中的JavaScript代码块. 在这种情况下,一段诸如 “” 这样的代码被插入了,它最后可能会也给现有的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元素也带上了红色, 如下所示. 在某些场景中,黑客可能会插入一段带有背景样式越苏,这可能会显示出原本不要被显示的背景,给最终用户带来糟糕的体验.

2015618103229268.png (1024×254)

<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>
登入後複製

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板