Chrome 的扩展程序系统会强制执行相当严格的默认内容安全政策 (CSP)。
政策限制很简单:脚本必须脱机移至单独的
JavaScript 文件,必须转换内嵌事件处理脚本才能使用 addEventListener
,而 eval()
已停用。Chrome 应用有更严格的政策,我们对安全性非常满意
政策所提供的属性。
不过,我们知道还有各种库都使用类似 eval()
和 eval
的结构,例如
new Function()
,用于优化性能和易于表达。模板库
尤其容易采用这种实施方式。虽然某些环境(如 Angular.js)支持 CSP out
许多热门框架尚未更新为与 Android Studio 兼容的
扩展程序的少了 eval
的世界。因此,事实证明,取消对该功能的支持
或性能超出预期的问题
本文档介绍沙盒是一种可在您的项目中添加这些库的安全机制 同时又不影响安全性为简洁起见,我们将全程使用附加信息一词,但 这一概念同样适用于应用。
为何要使用沙盒?
eval
在扩展程序中很危险,因为它执行的代码可以访问
扩展程序的高权限环境提供了大量功能强大的 chrome.*
API,
严重影响用户的安全和隐私;我们最担心的是简单的数据渗漏问题。
提供的解决方案是一个沙盒,在此沙盒中,eval
无需访问
或扩展程序的高价值 API。没有数据、不使用 API,也没有关系。
为此,我们会将扩展程序软件包内的特定 HTML 文件列为已沙盒化。
每当有沙盒机制加载网页时,系统都会将其移动到唯一来源,并会被拒绝
对 chrome.*
API 的访问权限。如果通过 iframe
将此沙盒化页面加载到扩展程序中,
然后向其传递消息,让其以某种方式处理这些消息,然后等待它为我们传回
结果。这种简单的消息传递机制为我们提供了安全纳入由 eval
驱动的一切所需的一切
代码生成。
创建和使用沙盒。
如果您希望直接查看代码,请下载沙盒示例扩展程序 关闭。这是一个基于 Handlebars 构建的小型消息传递 API 的有效示例 模板库,它应该会为您提供开始操作所需的一切。为了 在这里,我们一起来看看这个示例。
列出清单中的文件
应该在沙盒中运行的每个文件都必须在扩展程序清单中列出,方法是添加
sandbox
属性。这是非常重要的一步,很容易被忘记,因此请仔细检查
您的沙盒文件会在清单中列出在此示例中,我们巧妙地对文件进行沙盒化
名为“sandbox.html”清单条目如下所示:
{
...,
"sandbox": {
"pages": ["sandbox.html"]
},
...
}
加载沙盒文件
为了对沙盒化文件执行一些有趣的操作,我们需要在
可以通过该扩展程序的代码进行处理在此示例中,sandbox.html已加载到
扩展程序的活动页 (eventpage.html) 通过 iframe
.eventpage.js 包含代码
该函数通过查找 iframe
并在其 contentWindow
上执行 postMessage
方法。该消息是一个对象
包含两个属性:context
和 command
。我们稍后将对这两者进行深入探讨。
chrome.browserAction.onClicked.addListener(function() {
var iframe = document.getElementById('theFrame');
var message = {
command: 'render',
context: {thing: 'world'}
};
iframe.contentWindow.postMessage(message, '*');
});
postMessage
API 的一般信息,请参阅关于 MDN 的 postMessage
文档 。非常完整,值得一读。尤其要注意,只有当数据可序列化时,才可以来回传递数据。例如,函数就不是。做一些危险的事情
加载 sandbox.html
后,它会加载 Handlebars 库,创建并编译内嵌的
这就像 Handlebars 建议那样:
<script src="handlebars-1.0.0.beta.6.js"></script>
<script id="hello-world-template" type="text/x-handlebars-template">
<div class="entry">
<h1>Hello, !</h1>
</div>
</script>
<script>
var templates = [];
var source = document.getElementById('hello-world-template').innerHTML;
templates['hello'] = Handlebars.compile(source);
</script>
不会失败!虽然 Handlebars.compile
最终使用的是 new Function
,但一切正常
完全符合预期,我们最终在 templates['hello']
中得到了一个已编译的模板。
传回结果
我们将设置接受命令的消息监听器,以便使用此模板
“事件”页面我们将使用传入的 command
来确定应执行的操作(您可以
想想不仅仅进行渲染创建模板?或许要在
并且 context
会直接传递到模板中进行呈现。所呈现的 HTML
将传递回事件页面,以便扩展程序稍后对它执行一些有用的操作:
<script>
window.addEventListener('message', function(event) {
var command = event.data.command;
var name = event.data.name || 'hello';
switch(command) {
case 'render':
event.source.postMessage({
name: name,
html: templates[name](event.data.context)
}, event.origin);
break;
// case 'somethingElse':
// ...
}
});
</script>
返回到“活动”页面,我们会收到此消息,并使用 html
执行一些有趣的操作
传递的数据。在此示例中,我们仅通过桌面通知发出语音提示
完全可以放心地将此 HTML 用作扩展程序界面的一部分。通过以下方式插入:
innerHTML
不会造成明显的安全风险,即使沙盒遭到完全入侵,
就无法将危险的脚本或插件内容注入到
高权限扩展程序上下文
这种机制使模板化变得简单直接,但当然不限于模板化。不限 在严格内容安全政策下无法正常运行的代码可以被沙盒化;在 实际上,对那些能够正常运行的扩展程序组件进行沙盒化往往很有帮助, 将程序的各部分限制在运行所需的最小权限集内, 正确执行。Google 的编写安全的 Web 应用和 Chrome 扩展程序演示文稿 2012 年 Google I/O 大会提供了这些技术的实际应用示例,值得您花 56 分钟的时间 。