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访问对象/方法时运行代码是不可能的.
我知道,如果通过另一个未重新定义的对象/函数间接访问这些方法,仍然可以间接访问这些方法.我们假设我也重新定义了这些.
具有足够的对象列表和作为内容对象的函数的沙箱代码是否安全?
在这种情况下,什么会留下攻击向量?
代码应该在Firefox,Chrome,IE(10 +),Opera,Safari中运行.
不,这不安全.
无论您使用代码的执行环境如何处理with,仍然可以使用以下技巧检索"真正的"全局对象:
var window = (function(){ return this }).call(undefined);
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为Function.call它将使用全局对象作为this其显式传递为undefined或的值null.