微前端学习笔记(3):前端沙箱之JavaScript的sandbox(沙盒/沙箱)

微前端学习笔记(3):前端沙箱之JavaScript的sandbox(沙盒/沙箱)
最新回答
瑾沫流年

2021-04-21 04:50:46

沙盒(Sandbox)机制旨在确保代码的安全性,限制其权限以防止恶意或不受信任的脚本访问敏感资源或干扰其他程序执行。通过在沙盒环境中运行代码,可以将其行为限制在安全范围之内。

沙盒是一种隔离机制,允许程序在独立环境中运行,避免对外界程序造成影响,保障系统安全。在开发中,沙盒环境通常用于服务器中通过Docker创建容器,或在 Codesandbox中运行代码示例,以及在程序中执行动态脚本。

微前端框架主要负责两个工作:一是实现JS沙盒,二是将沙盒内的执行结果输出为WebComponents,插入到页面中。

沙盒能够确保每个前端应用拥有独立的上下文环境、页面路由和状态管理,避免相互干扰。

实现JavaScript沙盒的方法有两类:通过iframe或ShadowRealm在原生环境上实现,以及利用JS特性(主要基于Proxy)实现。

利用iframe实现沙盒是通过其天然的隔离机制和postMessage通讯机制。在iframe中运行的脚本只访问当前iframe的全局对象,不会影响父页面功能,提供简单、安全的实现方式。腾讯的无界沙箱采用此方案。

使用iframe沙盒有一些限制,需要配置来解除限制。实际工程中,可以参考《让iframe焕发新生》一文,使用封装的框架wujie实现。

无界沙箱模式在一张页面上激活多个子应用,利用iframe独立执行,并通过location和history管理路由,支持浏览器前进、后退操作。

核心点包括:iframe数据劫持和注入、iframe与shadowRoot副作用处理。实现细节在无界源码中。

ShadowRealm是一个ECMAScript标准提案,允许创建多个高度隔离的JS运行环境,具有独立的全局对象和内建对象。但目前仍处于提案阶段。

WebWorker提供独立线程作为沙箱环境,适合作为底层实现,但不常提及。腾讯无界方案展示了其优势。

IIFE(立即执行匿名函数)实现简易沙箱,可限制变量访问,但只能实现基本隔离。

with + new Function提供访问全局变量和局部变量的能力,但存在全局作用域污染风险。

利用with和Function结合Proxy实现ES6 Proxy,通过拦截器get和set对window进行代理,实现全局环境的隔离。

沙箱逃逸是极端情况下的安全挑战,通过设置Symbol.unScopables为true来绕过with作用域限制。

沙盒实现包括简单代码实现和多实例模式,分别通过with块和Proxy对象隔离执行环境。单实例模式只支持记录变化,多实例模式则在微应用间创建独立的沙箱环境。

基于属性diff的沙箱机制在不支持ES6的环境中使用普通对象快照实现存储与恢复,用于更新子应用环境。qiankun中提供了此降级方案。

总结:沙盒机制是实现代码安全隔离的有效手段,通过不同方法实现沙箱,可以满足不同场景的需求。在实现时需考虑限制与优化,确保安全性和性能。