Artikel ini menunjukkan penyelesaian berbeza untuk XSS (skrip merentas tapak) dan cara menggunakan SCE ($sceProvider) dan membersihkan ciri perkhidmatan dalam AngularJS untuk mengendalikan XSS dengan betul. Jika saya terlepas sesuatu yang penting sila komen/cadang terus. Juga, maafkan saya atas kesilapan menaip.
Perkara berikut akan menjadi tumpuan perkara yang akan saya bincangkan seterusnya:
Gunakan arahan ng-bind untuk transkod HTML
Anda boleh menggunakan arahan ng-bind untuk mengubah kod keseluruhan halaman web. Ia akan mengubah kod semua teg HTML tetapi masih memaparkannya sebagaimana adanya. Kod berikut menunjukkan penggunaan 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>
Gambar di bawah membuktikan kenyataan di atas. Perhatikan kod HTML dalam medan input. Ia betul-betul sama seperti dalam halaman HTML.
Sisipkan HTML dengan cara yang selamat, atau gunakan arahan ng-bind-html untuk mengabaikan elemen seperti "skrip"
Ini adalah kunci untuk menyelesaikan serangan XSS, anda masih perlu memberi perhatian kepada elemen seperti "img" (disertakan sebagai sebahagian daripada senarai putih; serta elemen kosong) kerana ia boleh digunakan dalam halaman web anda. Paparkan sebarang imej (termasuk yang menyalahi undang-undang) padanya, oleh itu, ia juga mungkin mempunyai kesan negatif pada halaman web anda Menggunakan arahan ng-bind-html, tag JavaScript AngularJS seperti "skrip" boleh diabaikan secara langsung. Arahan bind-html menilai ungkapan dan memasukkan HTML yang terhasil ke dalam elemen dengan cara yang selamat Untuk situasi di mana pengguna akan memasukkan input yang mengandungi kandungan HTML (seperti dalam ulasan), letakkannya dalam arahan ng-bind-html. Ini memastikan bahawa teks dikodkan sebagai senarai putih aksara HTML selamat >
Elemen kosong:
Dua elemen berikut perlu dielakkan kerana kandungannya tidak dipercayai Dalam kes ini, jika anda ingin memaparkannya, anda perlu menggunakan perkhidmatan $sce dan memanggil kaedah trustAsHtml Angular untuk melaksanakan elemen yang dinyatakan di bawah
下面这张图片展示了当在文本域中输入HTML代码,Angular用一种安全的方式插入到DOM时,是什么样子的. 注意 “img” 元素是上述列表中空元素的一份子. 因为代码被输入到了文本域中,作为”img"出现的图片被放到了受信任的列表(白名单)中。
信任并插入整段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元素也带上了红色, 如下所示. 在某些场景中,黑客可能会插入一段带有背景样式越苏,这可能会显示出原本不要被显示的背景,给最终用户带来糟糕的体验.
<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>