UNPKG

@web-sandbox.js/web-sandbox

Version:
172 lines (121 loc) 5.48 kB
# WebSandbox > WebSandbox 基于 Realm Stage 2 规范实现,前一段时间 Realm 进入了 Stage 3,它有了非常大的 API 变更,这使得 WebSandbox 需要重新进行适配。 WebSandbox 的目标是构建一个安全且轻量化的浏览器虚拟化容器,它采用使用 Web 标准技术来构建,它的使用场景: * 作为 Web 应用的插件的安全运行环境、提供开放式的插件系统 * 让不同的技术栈、版本的组件能够在同一个页面中运行,避免陷入重构的泥潭 [https://web-sandbox.js.org/](https://web-sandbox.js.org/) ## 安全模型 * JS 语言安全——Realm: 基于 TC39 最新草案实现 * CSS 安全——Shadow DOM: Web 正式标准 * HTML 安全——Sanitizer: 基于 W3C 草案实现 * 内容安全策略——CSP: 基于 W3C 正式标准实现 ## 资源虚拟化 ### DOM 树 WebSandbox 拥有完整的 DOM 树结构,这些使用 ShadowRoot 隔离。 ```html <web-sandbox> ——— window #shadow-root ——— document <html> ——— document.documentElement <head></head> ——— document.head <body></body> ——— document.body </html> </web-sandbox> ``` ### 内容安全策略 可以通过 CSP 配置来控制应用内部的脚本、样式、链接、表单、网络请求等行为。 ```html <web-sandbox name="sandbox-evaluate" csp=" default-src 'none'; script-src 'self' 'unsafe-inline' 'unsafe-eval' cdn.jsdelivr.net; style-src * 'unsafe-inline' cdn.jsdelivr.net; navigate-to 'self' web-sandbox.js.org; "> </web-sandbox> ``` ### 本地存储 拥有专属的本地存储空间,主文档或者父 WebSandbox 可以对它进行管理。 ```html <web-sandbox id="box" text=" localStorage.setItem('test', 1) "> </web-sandbox> ``` ### Web Components 拥有完整的 Web Components 虚拟化实现,WebSandbox 内部注册的自定义元素不会影响主文档。 ### Viewport WebSandbox 中的 CSS 无法影响主文档,包括设置了 `position: fixed` 元素、`:host` 选择器。 ### Task `requestAnimationFrame()``setTimeout()``setInterval()` 等异步任务将随着 WebSandbox 销毁而自动结束。 ### ChildWebSandbox WebSandbox 的应用内部也可以使用 WebSandbox,并且将继承内容安全策略。 ```html <web-sandbox id="box" text=" const sandbox = document.createElement('web-sandbox'); sandbox.src = './child.js'; document.body.appendChild(sandbox); "> </web-sandbox> ``` ## 标签 ```html <web-sandbox name="application-name" src="https://cdn.jsdelivr.net/npm/application-name@3/dist/web-sandbox-application.demo.js"> </web-sandbox> ``` ## 属性 ### name 沙箱应用名称。该名称可以用作为沙箱内 `window.name` 的值(也将作为内部分配本地缓存资源的命名空间)。 ### src 远程沙箱脚本地址。 ### text 本地的脚本内容。 ### contentWindow 沙箱内的 `window` 对象。只有在 `<web-sandbox>` 插入到文档后才可以访问到。 ### contentDocument 沙箱内的 `document` 对象。只有在 `<web-sandbox>` 插入到文档后才可以访问到。 ### csp 内容安全策略。CSP 可以精细化的指定沙箱的运行权限,例如限制数据请求等、禁止运行远程脚本等。这是 [CSP](https://www.w3.org/TR/CSP2/) 规范的子集。 如果不设置 `csp` 属性,那么 `<web-sandbox>` 将会启用默认指令 `default-src none`。 支持的指令: * `default-src` * `connect-src` * `script-src` * `style-src` * `form-action` * `navigate-to` `source` 支持的关键字: * `'none'` * `'self'` 示范: ```html <web-sandbox name="sandbox-evaluate" title="WebSandbox View" csp=" default-src 'none'; script-src 'self' 'unsafe-inline' 'unsafe-eval' cdn.jsdelivr.net; style-src * 'unsafe-inline' cdn.jsdelivr.net; navigate-to 'self' web-sandbox.js.org; "> </web-sandbox> ``` 更多 CSP 介绍:<https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP> ## 限制 * 受 Realm 垫片实现影响,远程的脚本与样式必须允许同源访问 * 受 Realm 垫片实现影响,脚本中在严格模式下运行 * 受 Realm 垫片实现影响,影响,脚本中不能包含 HTML 注释语句 `<!--->` * 受 Realm 垫片实现影响,影响,脚本中不能使用 ES6 `import` 导入模块 * 受 Realm 垫片实现影响,影响,脚本中不能**直接**使用 `eval()` 语句;允许**间接**使用,例如 `(0, eval)(code)`。这个限制会导致一些依赖 `eval()` 语句动态编译模板的框架无法运行,这些模板必须在构建阶段编译后才能运行,例如 Vue * 受内置安全策略影响,不能使用主文档定义好的自定义元素 * 受内置安全策略影响,脚本通过 `element.innerHTML` 等类似的 API 插入内容的时候可能会被过滤掉有危险的标签与属性 * 受内置安全策略影响,主文档无法通过 `localStorage` 给沙箱脚本共享数据,因为 `localStorage` 被隔离 * 受内置安全策略影响,无法捕获脚本运行时的全局错误,只允许主文档捕获 * 不支持 CSS 的 vw/vh 单位 * 不支持 CSS 媒体查询 * 不支持 CSS 的 `import` 语句导入样式 受安全策略与项目进展的影响,浏览器的 API 以白名单的方式提供,细节请查阅 [Web API 兼容性报告](https://web-sandbox.js.org/docs/web-compat/)。