4

我想创建一个 HTML+JS 环境,用户可以在其中输入和运行任意 JavaScript 代码,这些代码将在给定的 jail 对象的上下文中执行。我已经建立了一个游乐场来说明我到目前为止所拥有的

这个做得不错:

  • 基本评价工作:
    • 输入:2 + 2
    • 输出:4
  • this返回监狱对象
    • 输入:this
    • 输出:[object Object]
  • this.hello()运行预期的方法
    • 输入:this.hello()
    • 输出:hello world!
  • 用户可以设置自己的功能并在以后执行它们:
    • 输入:this.foo = function() { return 42; }
    • 输出:function () { return 42; }
    • 输入:this.foo()
    • 输出:42
  • 尝试访问一些我想从监狱上下文中“隐藏”的对象失败:
    • 输入:hidden
    • 输出:ReferenceError: hidden is not defined

但是,它完全无法隐藏全局可访问的属性,例如windowor documentfor user:

  • 输入:window
  • 电流输出:[object Window]
  • 期望的输出:ReferenceError: window is not defined

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

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

1 回答 1

5

如果它是客户端并且您可以保证使用现代浏览器,请改用网络工作者;它们更安全,您还可以阻止无限循环占用主线程,并通过调用来实现超时Worker#terminate

为每次执行启动一个新的工作人员:

var worker = new Worker('path/to/evaluator.js');

从worker接收消息:

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

发送代码以执行:

worker.postMessage(someCode);

在工人中,听:

onmessage = function (e) {
    postMessage(eval(e.data));
};

并且确保terminate在收到消息后也调用,因为工人可以调用postMessage自己。(您可以阻止这种情况,但实际上没有意义。)

Web Worker 无法访问主执行上下文中的任何内容,它们在另一个线程上运行,并且由浏览器实现,因此它们比典型的 delete-dangerous-things 沙箱安全得多。

但是,他们确实XMLHttpRequest可以访问;请参阅是否可以沙盒 JavaScript 在浏览器中运行?如果这是一个问题,其他方法。

于 2014-06-04T02:33:46.833 回答