zoukankan      html  css  js  c++  java
  • 前端沙箱简介

    沙箱,即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中的沙箱

  • 相关阅读:
    MySQL表的四种分区类型
    微信开发配置(Yii框架下的开发)
    一道编程题—输出字符串内重复的数字
    无序数组内查找指定值(快速查找)
    指针
    chmod
    cookie和session的区别
    使用keytool生成证书
    人大金仓修改最大连接数
    数据库链接地址
  • 原文地址:https://www.cnblogs.com/fuGuy/p/13535437.html
Copyright © 2011-2022 走看看