前端沙箱简介

沙箱,即sandbox,顾名思义,就是让你的程序跑在一个隔离的环境下,不对外界的其他程序造成影响

Nodejs Sandbox

在nodejs中主要是依赖于vm模块

const vm = require('vm');
const x = 1;
const sandbox = { x: 1 };
vm.createContext(sandbox); // 创建沙箱

const code = 'x += 40; var y = 1;';
vm.runInContext(code, sandbox);

console.log(sandbox.x); // 41
console.log(sandbox.y); // 1

console.log(x); // 1;  

可以通过传入Object.create(null)防止通过原型链逃逸

const vm = require('vm');
const x = 1;
const sandbox = Object.create(null);
sandbox.x=1
vm.createContext(sandbox); // Contextify the sandbox.

const code = 'x += 40; var y = 1;';
vm.runInContext(code, sandbox);

console.log(sandbox.x); // 41
console.log(sandbox.y); // 1

console.log(x); // 1;  

借助iframe实现沙箱

<iframe sandbox src="..."></iframe>

遇到的限制

  • script脚本不能执行
  • 不能发送ajax请求
  • 不能使用本地存储,即localStorage,cookie等
  • 不能创建新的弹窗和window
  • 不能发送表单
  • 不能加载额外插件比如flash等

但可以对这个iframe标签进行一些配置

然后就可以通过postMessage进行通信,但需要注意不要让执行代码访问到contentWindow对象

with + new Function

with的块级作用域下,变量访问会优先查找你传入的参数对象,之后再往上找,所以相当于你变相监控到了代码中的“变量访问”

function compileCode(src) {
    src = 'with (exposeObj) {' + src + '}'
    return new Function('exposeObj', src)
}
function compileCode(src) {
    src = `with (exposeObj) { ${src} }`
    return new Function('exposeObj', src)
}

function proxyObj(originObj) {
    let exposeObj = new Proxy(originObj, {
        has: (target, key) => {
            if (["console", "Math", "Date"].indexOf(key) >= 0) {
                return target[key]
            }
            if (!target.hasOwnProperty(key)) {
                throw new Error(`Illegal operation for key ${key}`)
            }
            return target[key]
        },
    })
    return exposeObj
}

function createSandbox(src, obj) {
    let proxy = proxyObj(obj)
    compileCode(src).call(proxy, proxy) //绑定this 防止this访问window
}

const testObj = {
    value: 1,
    a: {
        b: { c: 1 }
    }
}
// 访问原型链实现了沙箱逃逸
createSandbox(`a.b.__proto__.toString = ()=>{
   console.log(a)

};a.b.__proto__.toString()`, testObj)

with + new Function 还是有很多潜在问题的,没有完全的隔离上下文,没有完全独立的执行进程,所以会导致很多潜在问题

参考:说说JS中的沙箱

原文地址:https://www.cnblogs.com/fuGuy/p/13535437.html