将"with(...){...}"中的关键文字声明为在其中运行的沙箱代码是否安全?

try*_*lly 4 javascript security sandbox code-injection with-statement

我避免使用eval()或从字符串创建的函数.但是当我需要运行一些可以由用户输入的Javascript子集时,我很想使用它只是因为它将为我节省很多编写词法分析器/解析器和解释器的工作.

说我想运行这段代码:

a.toLowerCase() === 'xyz' || b == 1 || /pqr/.test(c)
Run Code Online (Sandbox Code Playgroud)

本机方法是将它传递到eval()这样:

with({a: ..., b: ..., c: ...}) {
    ret = eval(code);
}
Run Code Online (Sandbox Code Playgroud)

我不能确定code总是包含如上所述的非关键代码.这开启了运行恶意代码的可能性.

我想过将一个重新定义关键浏览器对象的对象传递with给实际数据,如:

var obj = {
   // list incomplete ;)
   console: true, XMLHttpRequest: true, document: true, window: true, addEventListener: true, removeEventListener: true, parent: true, top: true, history: true, ..., 

   // actual data
   a: ..., b: ..., c: ...
};

with (obj) {
   ...
}
Run Code Online (Sandbox Code Playgroud)

with访问对象/方法时运行代码是不可能的.

我知道,如果通过另一个未重新定义的对象/函数间接访问这些方法,仍然可以间接访问这些方法.我们假设我也重新定义了这些.

具有足够的对象列表和作为内容对象的函数的沙箱代码是否安全?

在这种情况下,什么会留下攻击向量?

编辑1:

代码应该在Firefox,Chrome,IE(10 +),Opera,Safari中运行.

dus*_*uff 7

不,这不安全.

无论您使用代码的执行环境如何处理with,仍然可以使用以下技巧检索"真正的"全局对象:

var window = (function(){ return this }).call(undefined);
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为Function.call它将使用全局对象作为this其显式传递为undefined或的值null.