【问题标题】:JavaScript WebWorker Isolated WorldJavaScript WebWorker 孤立的世界
【发布时间】:2023-02-02 05:21:24
【问题描述】:

在 Web Worker 中(不是在主线程上;这个问题是不是重复)是否可以在单个 Web Worker 线程(1 个线程)中运行多段不安全代码(由多个不同用户提供的代码),所有这些都在同一线程上,这样这些代码:

  1. 无法访问彼此的上下文
  2. 无法访问 Web Worker 的上下文
  3. 无法访问主线程域的存储(例如 indexeddb、localstorage)

    用户提供的代码不应该能够设置工人的 onmessage。

    我在 WebWorker 中寻找类似 iFrame 上下文的东西。

    然而!在任何回答者建议使用闭包或试图覆盖 onmessage / globalThis 对象等之前,有近无限获取全局范围访问权限的偷偷摸摸的方法。例如,你知道吗:

    try {throw ( function(){return this} );}
    catch (get_scope){...}
    

    会不会break出任何闭包?


    我发现这个关于 V8 绑定(Chrome,不是 FireFox)的旧参考资料说网络工作者有 0 个孤立的世界。 https://chromium.googlesource.com/chromium/src.git/+/62.0.3178.1/third_party/WebKit/Source/bindings/core/v8/V8BindingDesign.md#world

    我也发现了这个比较老的研究https://seclab.stanford.edu/websec/jsPapers/csf09-camera-ready.pdf 关于使用 JS 来隔离 JS,但是他们的解决方案是只允许特殊代码运行(在分析源文本之后),我希望所有代码都运行。

    但是两个都太老了。。。

【问题讨论】:

  • 我想你可以通过不同的来源加载。例如。您可以在指向同一服务器的 DNS 中创建另一个 a 记录,然后通过它加载 JS 文件。
  • Will break out of any closure?,如果你把'use strict';放在用户提供的代码之前,它会返回undefined吗?
  • 请不要尝试解决随机示例。关键是有无限种方法可以达到相同的结果:代码总能找到一种方法来访问全局上下文。 (例如,添加“use strict”可以通过...编写一个新函数来规避。:-|)除非浏览器本身有一些设计来隔离代码。 Web Worker 的 importScripts() 对于安全上下文是受域限制的。我将如何从不同的来源加载?但即便如此......因为其中一段代码确实来自主页上的文本输入......
  • 你需要检查这个,但是默认的同源脚本都没有比同源更少的访问权限,所以如果你做了importScripts('https://user.mydomain.com');还有另一个选择,就是使用iFrame无论如何,因为它已经是一个WebWorker它有自己的 JS 运行时,使 iFrame 隐藏,没有人会更聪明.. :)
  • 我想我毕竟必须使用 iFrame。在 FireFox nightly 中,importScript() 是不允许的,但是 import / dynamic import() 仍然被禁用,所以 web workers 完全崩溃了。 :-( 我将手动序列化 iFrame 函数的输入/输出。我会写下我的结论并在将来(希望如此)更新 FireFox 时更新此答案。

标签: javascript browser isolation


【解决方案1】:

你不能在 web worker 中有 iframe,因为没有 DOM。
但是该列表中的所有内容都可以通过完全按照您所说的来实现:覆盖全局对象。

要从全局上下文中删除属性以便任何人都无法访问它,请沿着self 的原型链向上走。您还可以使用Object.freeze 使您的更改永久生效。

function deleteProperty( target, propertyName ) {
    while( target ) {
        delete target[ propertyName ];
        target = Object.getPrototypeOf( target );
    }
}

例如,调用deleteProperty( self, "postMessage" ) 将保证任何地方的任何代码都无法访问postMessage() 函数。

从您的列表中:

  1. 无法访问彼此的上下文

    这是什么意思? JavaScript 代码具有保护任何上下文的能力。

    function myFunc() { /* This context is protected */ }
    

    您运行的代码片段可以根据需要保护自己的上下文。所有开发人员在编写代码时都知道这一点。

    1. 无法访问 Web Worker 的上下文

    这与第 1 点相同。web worker 中的所有内容都有一个全局上下文。如果您想控制该上下文,进行更改,然后致电Object.freeze()

    1. 无法访问主线程域的存储(例如 indexeddb、localstorage)

    同样,只需删除对它的访问:deleteProperty( self, "indexedDB" )

    用户提供的代码不应该能够设置工人的 onmessage。

    设置自己的监听器,然后修改全局上下文:

    self.addEventListener( "message", messageEvent => { /* ...  */ } );
    deleteProperty( self, "onmessage" );
    deleteProperty( self, "addEventListener" );
    Object.freeze( self );
    

    只要你控制运行的代码第一的在您的工作人员中,您可以根据需要配置全局上下文。围绕您所做的更改没有“偷偷摸摸”的方法,只需彻底处理您想要限制的任何访问即可。

【讨论】:

  • 遗憾的是 FF 的市场份额正在减少,但原因很明显。放弃对桌面网络应用程序的支持对我来说是最后一根稻草。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-23
  • 2012-05-23
  • 1970-01-01
  • 2017-07-07
相关资源
最近更新 更多