V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
Shook
V2EX  ›  JavaScript

这样的 javascript 沙盒足够安全吗?

  •  
  •   Shook · 2020-11-29 23:08:14 +08:00 · 3812 次点击
    这是一个创建于 1457 天前的主题,其中的信息可能已经有所发展或是发生改变。

    想要做个搜索框,支持简易的数学计算,比如 100+100 。

    想着用 evel 来做应该足够简单,就是不知道是否够安全。 如果够安全,似乎开可以开放一些函数,提供 context 供用户自己写点具体的东西。 比如让用户自定义搜索框的行为。

    这段代码是从知乎的腾讯云技术社区发的文章里拿来的。

    模块:

    const codeProxies = new WeakMap();
    const compileCode = (content) => {
      const code = new Function('context', `with(context) { ${content} }`);
    
      return (data = {}) => {
        if (!codeProxies.has(data)) {
          codeProxies.set(data, new Proxy(data, {
            has: () => true,
            get: (target, key) => key === Symbol.unscopables ? void 0 : target[key],
          }));
        }
        return code(codeProxies.get(data));
      };
    };
    

    再次封装:

    export const compileFunction = (context, code) => {
      return compileCode(`
        return (function() { ${code} }).call({});
      `)(context);
    };
    

    使用:

    try {
      console.log(compileFunction({}, `return ${this.store.search};`));
    } catch(error) {
      console.log(error);
    }
    
    17 条回复    2020-11-30 14:32:20 +08:00
    zhuangzhuang1988
        1
    zhuangzhuang1988  
       2020-11-29 23:12:37 +08:00
    要不试试这个?
    https://mathjs.org/
    murmur
        2
    murmur  
       2020-11-29 23:14:10 +08:00
    eval 、new function 这种有的代码审核都不让过的,不要在这里玩骚操作,除非你确定后台给你的代码一定安全(至少不要把原有的东西搞砸),而且这部分接口的数据不会被入侵或者注入什么
    des
        3
    des  
       2020-11-29 23:17:52 +08:00
    不安全,你试试这个
    compileFunction({ console }, "console.log(this.constructor.constructor(\"return process\")())")
    iNaru
        4
    iNaru  
       2020-11-29 23:30:01 +08:00   ❤️ 1
    创建个可控跨源的 iframe sandbox,用 postMessage 通讯,随便 eval 。
    Shook
        5
    Shook  
    OP
       2020-11-29 23:37:23 +08:00
    @zhuangzhuang1988 这个好棒啊,谢谢!

    @des 这个用例走到了 catch,报错 process 不存在,但没有逃逸成功。
    des
        6
    des  
       2020-11-29 23:41:36 +08:00
    @Shook 你是用的浏览器吧
    浏览器的话试试这个 compileFunction({ }, "this.constructor.constructor('return top')().close()")
    codehz
        7
    codehz  
       2020-11-30 00:07:46 +08:00 via Android
    codehz
        8
    codehz  
       2020-11-30 00:09:11 +08:00 via Android
    我建议在 Realms 提案广泛可用之前别尝试折腾 js 实现 js 沙箱,
    自己写一个语言的解释器不香吗
    codehz
        9
    codehz  
       2020-11-30 00:11:56 +08:00 via Android
    whoami9894
        10
    whoami9894  
       2020-11-30 01:28:52 +08:00
    (()=>{}).constructor('return eval')()('prompt()')

    对 JS 这种语言就别想着自己实现沙盒了,vm2 这种专门做沙盒的项目都被打穿过好多次
    whoami9894
        11
    whoami9894  
       2020-11-30 01:38:18 +08:00
    按你计算器的需求,白名单限制下 [0-9\+\-\*\/\(\)]
    autoxbc
        12
    autoxbc  
       2020-11-30 02:59:44 +08:00
    一个前端运算的搜索框搞啥沙盒,用户自己攻击自己?
    rannnn
        13
    rannnn  
       2020-11-30 04:02:39 +08:00
    用 iframe
    xxxy
        14
    xxxy  
       2020-11-30 09:42:17 +08:00
    可能会导致 xss
    no1xsyzy
        15
    no1xsyzy  
       2020-11-30 10:14:58 +08:00
    别想着沙盒,还是重新实现一遍解释器靠谱。
    tobeyouth
        16
    tobeyouth  
       2020-11-30 11:19:47 +08:00
    很多年前做过类似的功能,个人感觉最好的方法是自己写一个针对算式的解析;
    这样更安全也更可控,还能兼容更多交互。
    jones2000
        17
    jones2000  
       2020-11-30 14:32:20 +08:00
    直接脚本发后台 nodejs, 在后台执行, 后台部署 docker,通过网管转发, 每个 docker 都是隔离的, 完全的。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1007 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 21:28 · PVG 05:28 · LAX 13:28 · JFK 16:28
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.