查看原文
其他

【第738期】WEB 安全:JSONP 沙箱技术实现

糖饼 前端早读课 2019-11-02

前言

本文由作者@糖饼投稿分享。


正文从这开始~


2005 年 12 月,Bob Ippolito 正式提出 JSONP,以实现跨域请求 JSON 数据。目前 JSONP 已经是业界流行的跨域数据获取方案。


JSONP 原理


它的原理是通过 <script> 标签实现跨域加载服务器动态输出的脚本,并执行指定函数回传数据。例子如下:


安全问题


引用站外脚本会让任何内容有机会注入到网站中:

  • 如果 JSONP 源被黑客攻陷,网站也可能会受到攻击。

  • 如果传输过程中被运营商劫持,网站可能会弹出广告(这个问题非常具有中国特色)。


JSONP 到目前为止依然还是一个未列入标准的技术方案,有人提出定义 JSONP 严格安全子集,使浏览器可以对 MIME 类别是 application/json-p 请求做强制处理,严格限定 JSONP 的权限,但是目前依然没有得到浏览器支持。


沙箱技术


iframe


如果利用 <iframe> 创造一个新的执行环境来加载站外脚本,这样可以为 JSONP 提供一层简单的防御。



但是 <iframe> 并非与页面完全隔离,攻击者使用 top 、 parent 等变量可以轻易的拿到页面的全局对象,使得防护失效。


HTML5 sandbox


HTML5 为 <iframe> 提供了 sandbox 属性,通过指令来控制 <iframe> 的权限。sandbox 开启后会隔离与父页面访问,页面与 <iframe> 通讯可以使用 HTML5 parent.postMessage(message, targetOrigin) 通讯。



启用 sandbox 后,如果 JSONP 脚本窃取 Cookie 或者篡改父页面都会被浏览器阻止。


IE 与 sandbox


IE 只有 IE10 以及更高版本支持 sandbox,在低版本 IE 浏览器中可以使用重写技术(override)来实现 sandbox 特性:重写 top、 parent、 docuemnt 等危险全局变量,使得外部脚本无法获取其引用。


黑魔法


在 IE 中删除、重写内置全局变量,常规的操作都将会失败,例如:


但定义同名函数却可以覆盖,这也是目前已知的唯一方式。



由于函数声明后会被“提升”,从而无法引用原始全局变量。



好在 IE 有 execScript() 这个独有的方法可以在全局环境编译字符串运行,结合闭包便可以私有化指定的全局变量。



这样只有内部函数可以获取到父页面引用进行跨窗口通讯,而外部脚本无论如何也拿不到真正的 parent 了,从而实现与父窗口隔离。


为了安全起见还可以全部重写 window 可枚举的属性以绝后患。



上述代码似乎一切都考虑妥当了?然而 IE9 却有个致命的问题:document 与 location 是常量,无法被覆盖。


document


由于 <iframe> 的 Cookie 是与父页面共享的,也就是说通过 document.cookie 可以轻松窃取到 Cookie。



好在 IE9 可以访问 document 的构造函数,而 document.cookie 是其原型上的一个 "getter"、"setter" 属性,如果删除原型的对应属性即可让其失效。


document 的继承关系为:HTMLDocument->Document->Node,清理其原型链即可。



至此,IE9 下 document 已经残废,其不但无法访问 document.cookie 甚至连 document.createElement 等基础 DOM API 都无法使用了。


location


IE9 下可以操作 location,由于 location 无法通过删除原型链的方式进行破坏,这意味着外部脚本有机会将 <iframe> 内部页面导航到新的地址中去。



<iframe> 被重载后,沙箱内的环境也将被重置,所有权限都将会被泄漏。如果新页面是第三方地址,浏览器会使用同源策略保护父页面,限制站外脚本数据获取与页面操作的行为,但是攻击者依然有机会发起钓鱼行为。



虽然无法破坏 location,IE9 却可以使用 unload 事件中实现沙箱“自杀”,从而阻止安全风险。



经过周密防范后,运行在此 <iframe> 的外部脚本几乎只有运行回调函数的权限,达到目标。


后记


基于 sandbox 的 JSONP 加载器代码已经开源:https://github.com/aui/jsonp-sandbox



关于本文

作者:@糖饼

原文:https://github.com/aui/jsonp-sandbox/issues/13


每天早读,三万同行相伴成长

欢迎投稿:181422448@qq.com

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存