javascript 沙箱实现

作者: nick 分类: js 发布时间: 2012-01-11 03:20 ė 6没有评论

从一个经典的跨域脚本应用说起:

JSONP 是一个流行的跨域获取数据的方案,它原理是向文档动态插入一个 script 标签,向远程服务器发起一个脚本请求,然后远程服务器返回一个定的回调函数并传入 JSON 数据,这样完成跨域数据交换。

如页面预先定义一个全局函数:

1 window.jsonp534533 = function (json) {
2 //...
3 }

向服务器发起 script 请求 JSONP

http://api.douban.com/jsonp?key=3435&type=music&callback=jsonp534533

服务器返回 js 文件

1 jsonp534533({
2 "code": 0
3 "data": [...]
4 })

JSONP 虽然很方便实现前端跨域,但是其弊端也是显而易见的:无法保证安全性。

由于是 script 直接执行,假若提供 JSONP 服务器返回了恶意代码 (如被黑客入侵),这样将会十分危险。恶意代码可以向页面插入广告或者直接重定向第三方站点、甚至可以窃取 cookie 用 N 种方式发送到第三方服务器,这些都直接威胁站点安全。

有没有一种纯前端的方案可以安全的加载 JSONP 呢?我们可以提供沙箱环境来加载外部脚本。

javascript 沙箱

一个安全的 JSONP 脚本它只给回调函数传入数据而不应该读写 document,更严格一点是不能进行任何的 DOM 与 BOM 操作。基于此,我们可以利用空白 iframe 新建一个脚本执行环境,然后限制 iframe.contentWindow 的 DOM 与 BOM 方法,让这个环境中运行的脚本无法读写主页面,也无法发起任何通讯请求,这样理论上实现了一个 javascript 沙箱环境。

由于浏览器 DOM 与 BOM 实现机制不同,我们可以结合以下两种方式编码。

一、覆盖原生的方法与属性

  1. this.__proto__ = {} (现代浏览器)
  2. 设置全局同名函数(IE为主)
  3. 向文档插入一个同名 name 属性的 iframe (针对opera)

二、使用 HTML5 iframe “sandbox” 属性

HTML5 iframe “sandbox” 属性可以限制 iframe 内容的权限。这个属性目前只有 chrome 、 safari 、IE10 支持,而且这个属性可选项太少,虽然能够限制 ajax 请求,但无法阻止传统的跨域请求,如 new Image 或者 script 方式。

javascript 沙箱应用场景畅想

除了安全加载 JSONP 之外,沙箱机制还可以为社交平台实现安全 javascript API 提供可能:

由于安全问题,社交平台第三方 APP 大多以 iframe 形式载入,但是由于 iframe 本身的问题,这样体验远远不能达到“原生”应用的高度。针对此我们可以给 APP 开发者设计一个应用 API,让其只能在沙箱环境中操作 APP 自身的 DOM 与有限的公用 API,而没有访问全局对象的能力,从而实现体验与安全完美合一。

scriptSandbox 项目

scriptSandbox 是上述想法而创建了一个开源项目,正如本文所述,它实现了沙箱环境用来隔离 JSONP 可能出现的危险操作。scriptSandbox 项目主页:

http://code.google.com/p/script-sandbox/

特别说明:下载包中含有测试脚本 test.js, 它除了传递 JSONP 外,还模拟了 “危险” DOM 操作,你可以在不同浏览器中测试沙箱隔离能力。欢迎您在 test.js 写“危险”代码对沙箱进行攻击,若实现下面要求均算成功成功:

  1. 获取页面 document 访问能力
  2. 获取与服务器通讯能力
  3. 弹出对话框

欢迎您给我提交漏洞报告 :) 1987.tangbin(a)gmail.com

参考文档:
http://www.infoq.com/cn/news/2010/01/HTML-5-Sandbox-IFrame
http://w3help.org/zh-cn/causes/BX9045

原文:http://www.planeart.cn/?p=1732

本文出自 传播、沟通、分享,转载时请注明出处及相应链接。

本文永久链接: https://www.nickdd.cn/?p=1853

发表评论

您的电子邮箱地址不会被公开。

Ɣ回顶部