欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

AngularJS 使用$sce控制代码安全检查

程序员文章站 2022-05-30 20:58:40
由于浏览器都有同源加载策略,不能加载不同域下的文件、也不能使用不合要求的协议比如file进行访问。 在angularjs中为了避免安全漏洞,一些ng-src或者ng-in...

由于浏览器都有同源加载策略,不能加载不同域下的文件、也不能使用不合要求的协议比如file进行访问。

在angularjs中为了避免安全漏洞,一些ng-src或者ng-include都会进行安全校验,因此常常会遇到 一个iframe中的ng-src无法使用。

什么是sce

sce,即strict contextual escaping,我的理解是 严格的上下文隔离  ...翻译的可能不准确,但是通过字面理解,应该是angularjs严格的控制上下文访问。

由于angular默认是开启sce的,因此也就是说默认会决绝一些不安全的行为,比如你使用了某个第三方的脚本或者库、加载了一段html等等。

这样做确实是安全了,避免一些跨站xss,但是有时候我们自己想要加载特定的文件,这时候怎么办呢?

此时可以通过$sce服务把一些地址变成安全的、授权的链接...简单地说, 就像告诉门卫,这个陌生人其实是我的好朋友,很值得信赖,不必拦截它!

常用的方法有:

$sce.trustas(type,name);
$sce.trustashtml(value);
$sce.trustasurl(value);
$sce.trustasresourceurl(value);
$sce.trustasjs(value);

其中后面的几个都是基于第一个api使用的,比如trsutasurl其实调用的是trsutas($sce.url,"xxxx");

其中 type 可选的值为:

$sce.html
$sce.css
$sce.url //a标签中的href , img标签中的src
$sce.resource_url //ng-include,src或者ngsrc,比如iframe或者object
$sce.js

来自官网的例子:ng-bind-html

<!doctype html>
<html>
<head>
  <title></title>
  <script src="http://apps.bdimg.com/libs/angular.js/1.2.16/angular.min.js"></script>
</head>
<body ng-app="mysceapp">
  <div ng-controller="appcontroller">
   <i ng-bind-html="explicitlytrustedhtml" id="explicitlytrustedhtml"></i>
  </div>
  <script type="text/javascript">
    angular.module('mysceapp',[])
    .controller('appcontroller', ['$scope', '$sce',
     function($scope, $sce) {
      $scope.explicitlytrustedhtml = $sce.trustashtml(
        '<span onmouseover="this.textcontent="explicitly trusted html bypasses ' +
        'sanitization."">hover over this text.</span>');
     }]);
  </script>
</body>
</html>

实际工作中的例子:ng-src链接

<!doctype html>
<html>
<head>
  <title></title>
  <script src="http://apps.bdimg.com/libs/angular.js/1.2.16/angular.min.js"></script>
</head>
<body ng-app="mysceapp">
<div ng-controller="appcontroller">
  <iframe width="100%" height="100%" seamless frameborder="0" ng-src="{{trustsrc}}"></iframe>
</div>
  <script type="text/javascript">
    angular.module('mysceapp',[])
    .controller('appcontroller', ['$scope','$sce',function($scope,$sce) {
      $scope.trustsrc = $sce.trustas($sce.resource_url,"http://fanyi.youdao.com/");
      // $scope.trustsrc = $sce.trustasresourceurl("http://fanyi.youdao.com/");//等同于这个方法
     }]);
  </script>
</body>
</html>

还有点时间,接着给大家介绍angular中的ng-bind-html指令和$sce服务

angular js的强大之处之一就是他的数据双向绑定这一牛b功能,我们会常常用到的两个东西就是ng-bind和针对form的ng-model。但在我们的项目当中会遇到这样的情况,后台返回的数据中带有各种各样的html标签。如:

$scope.currentwork.description = “hello,<br><b>今天我们去哪里?</b>”
我们用ng-bind-html这样的指令来绑定,结果却不是我们想要的。是这样的

hello,

今天我们去哪里?

怎么办呢?

对于angular 1.2一下的版本我们必须要使用$sce这个服务来解决我们的问题。所谓sce即“strict contextual escaping”的缩写。翻译成中文就是“严格的上下文模式”也可以理解为安全绑定吧。来看看怎么用吧。

controller code:

$http.get('/api/work/get?workid=' + $routeparams.workid).success(function (work) {$scope.currentwork = work;});

html code:

<p> {{currentwork.description}}</p>

我们返回的内容中包含一系列的html标记。表现出来的结果就如我们文章开头所说的那样。这时候我们必须告诉它安全绑定。它可以通过使用$ sce.trustashtml()。该方法将值转换为特权所接受并能安全地使用“ng-bind-html”。所以,我们必须在我们的控制器中引入$sce服务

controller('transferworkstep2', ['$scope','$http','$routeparams','$sce', function ($scope,$http, $routeparams, $sce) {
$http.get('/api/work/get?workid=' + $routeparams.workid)
.success(function (work) {
  $scope.currentwork = work;
  $scope.currentwork.description = $sce.trustashtml($rootscope.currentwork.description);
});

html code:

<p ng-bind-html="currentwork.description"></p>

这样结果就完美的呈现在页面上了:

hello

今天我们去哪里?

咱们还可以这样用,把它封装成一个过滤器就可以在模板上随时调用了

app.filter('to_trusted', ['$sce', function ($sce) {
return function (text) {
  return $sce.trustashtml(text);
};
}]);

html code:

全选复制放进笔记

<p ng-bind-html="currentwork.description | to_trusted"></p>