【angularjs】如何使用$sce控制代码安全

21次阅读

共计 2372 个字符,预计需要花费 6 分钟才能阅读完成。

最近在做关于 angularjs 的项目,后续可能会分享一些关于 angularjs 的一些小知识或者常见问题!
今天分享的是关于 angularjs 如何使用 $sce 控制代码安全。
问题场景:需求要求,点击按钮,要通过一个 http 网址打开页面,但是这个页面要使用弹框而不能新开一个窗口,这时候我就想到了 iframe,大致代码如下:
在 controller 里面写到:
var url = ‘http://www.baidu.com’;
$scope.myUrl = url;
html 如下:
<iframe ng-src=”{{myUrl}}” height=”500″ width=”800″ scrolling=”yes”></iframe>
这时候问题来了,打开页面是空白的,然后控制台打印了“Error:[$interpolate:interr]”的类型错误:
获取页面元素也发现 iframe 里面的 src 值没有获取到:
在 js 里面打印 url 是有值的,在 html 里面用其他标签获取 url 也是有值的,所以最后把问题定位在了 iframe 上面,最后发现,angularjs 是没办法直接传 url 给 iframe 的 src 里面的,需要经过一定的安全过滤。
有两种办法可以解决:1、最直接最简单的方法,就是直接在 url 值外层套一个 $sce.trustAsResourceUrl(),在 controller 里面的 js 改写为:
var url = ‘http://www.baidu.com’;
$scope.myUrl = $sce.trustAsResourceUrl(url);
2、使用过滤器:新增过滤器
angular.module(‘app’, []).filter(‘iframeSrc’, [‘$sce’, function($sce) {
return function(val) {
return $sce.trustAsResourceUrl(val);
};
}])
在 html 里面使用过滤器:
<iframe ng-src=”{{myUrl | iframeSrc}}” height=”500″ width=”800″ scrolling=”yes”></iframe>
以上两种方法都可以解决 src 的取值问题,关键点就在于 $sce.trustAsResourceUrl() 上面。
$sce.trustAsResourceUrl() 是 angularjs 中防止用户注入 url 的一个安全检查方法。
································································································································
由此就引申出关于 $sce 的一些知识:
(1)在 angularJs 中为了避免安全漏洞,一些 ng-src 或者 ng-include 都会进行安全校验,因此常常会遇到一个 iframe 中的 ng-src 无法使用的问题
(2)什么是 SCE?SCE,即 strict contextual escaping,字面上我理解为严格的上下文访问之类的意思,不知道是否正确,但是从 SCE 的工作机制上看,他做的就是一种安全检查,将相关语境中存在的注入或者跨站攻击等风险干掉,从而将一些特定的内容(包括 html,url,css,js,resourceUrl)标记过信任内容再提供给页面使用。这些默认都是不被 angularjs 信任的,若是使用过程中有像我这样的需求的话,就可以使用 $sce 来进行授权信任。
(3)常用的 $sce 方法和使用场景:
$sce.trustAs(type,name); //type 包括:$sce.HTML,$sce.CSS,$sce.URL,$sce.RESOURCE_URL,$sce.JS,比如 trsutAsUrl 其实调用的是 trsutAs($sce.URL,”xxxx”);
$sce.trustAsHtml(value);
$sce.trustAsUrl(value); // a 标签中的 href,img 标签中的 src
$sce.trustAsResourceUrl(value); //ng-include,src 或者 ngSrc,比如 iframe 或者 Object
$sce.trustAsJs(value);
后面奉上官网的例子 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=&quot;Explicitly trusted HTML bypasses ‘ +
‘sanitization.&quot;”>Hover over this text.</span>’);
}]);
</script>
</body>
</html>

正文完
 0