分享一个安全实现JSONP跨域的插件

 

使用过JSONP跨域请求的都知道,JSONP就是发送一个请求从服务端返回一个JS函数,在WEB页面也定义一个相同函数,这样请求完毕后就可以执行JS了,

这样虽然很容易实现跨域交互,但是有一个弊端就是无法保证安全性,下面是我在一个博客中看到的解决方法,分享一下

 

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

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

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

 window.jsonp534533 = function (json) {
           //...
    }

 

向服务器发起 script 请求 JSONP

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

 

服务器返回 js 文件

jsonp534533({
        "code": 0
        "data": [...]
})

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

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

有没有一种纯前端的方案可以安全的加载 JSONP 呢?下面是我想到的一个方案:

javascript 沙箱

一个安全的 JSONP 脚本它只给回调函数传入数据而不应该读写 document,更严格一点是不能进行任何的 DOM 与 BOM 操作。基于此,我们可以利用空白 iframe 新建一个脚本执行环境,然后限制 iframe.contentWindow 的 DOM 与 BOM 方法,让这个环境中运行的脚本无法读写主页面,也无法发起任何通讯请求,包括 AJAX 方式 与 new Image() 、 script 方式等,与 这样理论上实现了一个 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 可能出现的危险操作。目前你也可以理解它是一个 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 

另外推荐一个也比较强大的跨域操作插件,一般我都用这个在博客园搜索sjax就有了

posted @ 2012-06-15 10:53  JieLee  阅读(1005)  评论(1编辑  收藏  举报
登录 发表评论 返回顶部