JavaScript 沙盒 : hide global variables from a given scope

标签 javascript scope closures isolation

我想创建一个 HTML+JS 环境,用户可以在其中输入和运行任意 JavaScript 代码,这些代码将在给定 jail 对象的上下文中执行。我设置了一个 playground to illustrate what I have so far .

这个做得还不错:

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

但是,它完全无法隐藏全局可访问的属性,例如用户的 windowdocument:

  • 输入:窗口
  • 当前输出:[对象窗口]
  • 期望的输出:ReferenceError: window is not defined

到目前为止,我想到的最好的解决方案是在 Jail 对象声明中用 undefinednull 填充我能想到的所有全局变量, 作为 illustrated in updated version .通过这种方式,它们似乎永远丢失在 jail 范围内,用户将无法访问它们。我的问题:

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

最佳答案

如果是客户端并且你可以保证使用现代浏览器,请使用 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,因为 worker 可以调用 postMessage 本身。 (你可以阻止它,但实际上没有意义。)

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

但是,他们确实可以访问XMLHttpRequest;见Is It Possible to Sandbox JavaScript Running In the Browser?如果这是一个问题,请使用其他方法。

关于JavaScript 沙盒 : hide global variables from a given scope,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24028008/

相关文章:

javascript - 三个js,spotlight/shadow camera cut off

javascript - Coffeeescript : how to declare private function that can be used from within Array. 减少?

javascript - for循环的范围问题

c# - C# 中的 Foreach(currentScope 中的类变量)

对象 : what alias should have "this" for passing into anonymous function? 内的 JavaScript 闭包

javascript - Spread 运算符将所有其他 props 传递给组件。 React.js

javascript - 单击时将嵌套数组/对象值显示到单独的元素中

javascript在for循环中设置属性

javascript - 通过将函数传递给 setCount 来修复陈旧闭包的副作用

c# - 在 C# 中的循环中捕获变量