我正在尝试以某种方式对功能进行沙盒化,以防止其执行被认为是恶意的操作。简单的例子:
const fn = (window, setTimeout) => {
console.log(`window: ${typeof window}`);
console.log(`setTimeout: ${typeof setTimeout}`);
};
fn (undefined, undefined);
// console output:
// window: undefined
// setTimeout: undefined
函数fn
无权访问window
或setTimeout
函数,因为它们被相同名称的参数隐藏。
为使此功能更有用,我想编写一个更高阶的函数来执行沙箱操作:
const sandbox = (fn) => (...args) => {
return ((window, setTimeout) => {
return fn.call(args);
})();
};
const maliciousFn = (a, b) => {
console.log(`a: ${a}`);
console.log(`b: ${b}`);
console.log(`window: ${typeof window}`);
console.log(`setTimeout: ${typeof setTimeout}`);
return 42;
};
const safeFn = sandbox(maliciousFn);
console.log (`maliciousFn returns: ${maliciousFn(13, 27)}`);
console.log (`safeFn returns: ${safeFn(13, 27)}`);
这不起作用,因为maliciousFn
已经捕获了window
的引用
和setTimeout
,附加包装器无法更改。
是否可以正确执行此操作?
背景:其背后的原因是我想编写一个沙盒eval
函数
这样就可以安全地评估任何给定脚本,而不会遭受恶意攻击。
当然,我必须隐藏所有全局变量,而不仅仅是window
和setTimeout
。但是一旦
适用于window
和setTimeout
,我也可以轻松添加所有其他全局变量。
const safeEval = sandbox(eval);
const result = safeEval(someScriptComingFromAnUnsafeSource);