JavaScript沙箱化:从给定作用域隐藏全局变量。

4

我想创建一个HTML+JS环境,用户可以输入和运行任意JavaScript代码,该代码将在给定的jail对象上下文中执行。我已经设置了一个游乐场来说明我目前的情况

这个做得还算不错:

  • 基本的评估工作:
    • 输入:2 + 2
    • 输出:4
  • this 返回 jail 对象
    • 输入:this
    • 输出:[object Object]
  • this.hello() 运行预期的方法
    • 输入:this.hello()
    • 输出:hello world!
  • 用户可以设置自己的函数并稍后执行它们:
    • 输入:this.foo = function() { return 42; }
    • 输出:function () { return 42; }
    • 输入:this.foo()
    • 输出:42
  • 尝试访问一些我希望从 jail 上下文中“隐藏”的对象会失败:
    • 输入:hidden
    • 输出:ReferenceError: hidden is not defined
然而,它完全无法隐藏全局可访问的属性,比如 window 或者 document,对于用户来说:

  • 输入:window
  • 当前输出:[object Window]
  • 期望输出:ReferenceError:window未定义

到目前为止,我想到的最好的解决方案就是在 Jail 对象声明中使用 undefinednull 填充我能想到的所有全局变量,正如 在更新版本中所示。这样,它们似乎永远丢失在 jail 的范围内,并且用户将无法访问它们。我的问题是:

  • 我是否正确?这样足够安全吗?
  • 是否有更好的方法,即在特定范围内真正取消定义全局内容,而不是用一些占位符值重写它们?
1个回答

6
如果是客户端,并且您可以保证使用的是现代浏览器,请使用Web Workers,它们更安全,您还可以通过调用Worker#terminate来停止无限循环并实现超时。
对于每次执行,请启动一个新的worker。
var worker = new Worker('path/to/evaluator.js');

接收来自工作者的消息:

worker.onmessage = function (e) {
    console.log(e.data);
};

发送要执行的代码:

worker.postMessage(someCode);

在worker中,监听:
onmessage = function (e) {
    postMessage(eval(e.data));
};

请确保在接收到消息后也要调用 terminate,因为工作线程可以自己调用 postMessage。(您可以防止这种情况,但实际上没有必要。)
Web Workers 无法访问主执行上下文中的任何内容,它们在另一个线程上运行,并且由浏览器实现,因此比典型的删除危险事物沙盒更安全。
然而,它们可以访问 XMLHttpRequest。如果这是一个问题,请参考在浏览器中运行的 JavaScript 是否可以进行沙箱隔离?以获取其他解决方案。

那就是我在寻找的! - Adam Arold

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接