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

2020-11-29 23:08:14 +08:00
 Shook

想要做个搜索框,支持简易的数学计算,比如 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);
}
3834 次点击
所在节点    JavaScript
17 条回复
zhuangzhuang1988
2020-11-29 23:12:37 +08:00
要不试试这个?
https://mathjs.org/
murmur
2020-11-29 23:14:10 +08:00
eval 、new function 这种有的代码审核都不让过的,不要在这里玩骚操作,除非你确定后台给你的代码一定安全(至少不要把原有的东西搞砸),而且这部分接口的数据不会被入侵或者注入什么
des
2020-11-29 23:17:52 +08:00
不安全,你试试这个
compileFunction({ console }, "console.log(this.constructor.constructor(\"return process\")())")
iNaru
2020-11-29 23:30:01 +08:00
创建个可控跨源的 iframe sandbox,用 postMessage 通讯,随便 eval 。
Shook
2020-11-29 23:37:23 +08:00
@zhuangzhuang1988 这个好棒啊,谢谢!

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

对 JS 这种语言就别想着自己实现沙盒了,vm2 这种专门做沙盒的项目都被打穿过好多次
whoami9894
2020-11-30 01:38:18 +08:00
按你计算器的需求,白名单限制下 [0-9\+\-\*\/\(\)]
autoxbc
2020-11-30 02:59:44 +08:00
一个前端运算的搜索框搞啥沙盒,用户自己攻击自己?
rannnn
2020-11-30 04:02:39 +08:00
用 iframe
xxxy
2020-11-30 09:42:17 +08:00
可能会导致 xss
no1xsyzy
2020-11-30 10:14:58 +08:00
别想着沙盒,还是重新实现一遍解释器靠谱。
tobeyouth
2020-11-30 11:19:47 +08:00
很多年前做过类似的功能,个人感觉最好的方法是自己写一个针对算式的解析;
这样更安全也更可控,还能兼容更多交互。
jones2000
2020-11-30 14:32:20 +08:00
直接脚本发后台 nodejs, 在后台执行, 后台部署 docker,通过网管转发, 每个 docker 都是隔离的, 完全的。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/730411

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX