V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
FurryR
V2EX  ›  分享创造

做了一种很新的前端 js 代码隔离方案

  •  
  •   FurryR ·
    FurryR · 2023-12-02 23:15:38 +08:00 · 2000 次点击
    这是一个创建于 384 天前的主题,其中的信息可能已经有所发展或是发生改变。

    大览

    secure-vm GitHub

    用最新的技术重新造了一遍 evel 的轮子。

    • ✅ 安全性高,免疫 import 攻击,自行试了一下 vm2 sandbox 之类的逃逸漏洞,均无效。
    • ✅ 几乎完全透明,把 vm() 换成 window 代码照样跑得起来。
    • ✅ 众所周知 electron 前端用 node:vm 会炸。secure-vm 不会。
    • ✅ 防调试一把手,代码内 debugger 无效,DevTools 看不到代码来源也下不了断点(在 Chromium 上显示未知或直接隐去具体代码,在 Firefox 上看不到代码内容)。
      • 🤔 但是 secure-vm 的内容被定位了就寄了。请尽量保护好依赖不被泄漏,或者自行验证(至少油猴插件用不了)。
    • ❌️ 不支持 ESM 。可以考虑用正则或者 babel 实现一下 ESM 支持,这个在 sesShadowRealm 实现有得抄。
    • ❌️ 不稳定,不支持 Opera,但是最新版的 ChromiumEdgeFirefoxSafari 是没问题的(其它的我还没测,IE ?哈哈)
    • ❌️ 没办法像 Worker.terminate() 那样想结束就结束。

    为啥要做?

    为了运行不可信任的用户代码/做微应用。可能有的场景有:

    • ⛹️ Playground 用来运行代码而不炸页面。
    • 🔒 某缩写 C 开头 W 结尾代理的 mixin 功能可能会用到,懂得都懂。
    • 🤔 少儿编程平台用来给小朋友们学习 Javascript 而不
    • 👽 跑点什么用户开发的微应用。
    • 👻 它就是很好玩所以我想试试。

    现行的前端可用沙箱有 ses 但仍在提案中,而这个大概是支持 ES2021 就能跑的程度了。

    相比 ses 这个 TC39 提案来说 secure-vm 的心智负担极小(就个 vm 函数),虽然部分细节不一致但是相对也值得了。

    未来

    目前这个项目只有一个指定 initalizer 的功能,用来和别的什么东西作兼容。未来还会支持:

    • 沙箱内和沙箱外共用各种全局函数从而实现兼容。
    • preventExtensionssetPrototype 之类功能的支持。
    • 允许设定禁止写入 prototype 或者覆盖各种外部 API 的属性。
    • 支持 ESM (当然这个可能很遥远,到时候再说)。

    总体来说

    这是一个又新又旧并且标准还未规定行为的 JS 沙箱。

    虽然目前在早期阶段,但我希望后面会越来越好的,加油!

    第 1 条附言  ·  2023-12-03 10:14:36 +08:00

    未来 JavaScript 标准中确实会出现沙箱。

    并且 ses 这个 npm 库我记得就是对这个 TC39 提案的一种实现。参照:

    SES is hardened JavaScript. SES stands for fearless cooperation. This package is a SES shim for JavaScript features proposed to ECMA TC39. Hardened JavaScript is highly compatible with ordinary JavaScript. Most existing JavaScript libraries can run on hardened JavaScript.

    但是 secure-vm 不强求严格模式,并且即使不开严格模式也不会出事。

    链接确实是忘加了,补充一下:

    https://www.npmjs.com/package/ses?activeTab=readme

    https://github.com/tc39/proposal-ses

    第 2 条附言  ·  2023-12-06 06:46:12 +08:00
    @musi 先生连源代码都没看完就开始展现中文互联网的魅力,实在是令人忍俊不禁。

    它是 iframe + proxy 没有错,你直接把 Function 传进去也会导致逃逸没有错,但是不知道先生有没有看到 iframe 函数里面一个 remove() 呢? secure-vm 在 iframe 内执行代码,但是这个 iframe 是一个已经被销毁的 iframe ,它甚至连 fetch 都访问不了,@musi 先生说的“现在前端都用这种方案”实在是令人笑掉大牙。
    shendaowu
        1
    shendaowu  
       2023-12-03 09:10:05 +08:00
    将来标准的 JavaScript 会支持类似沙箱的东西吗?我看 TC39 里的 ShadowRealm 好像是干这个的?你的“这个 TC39 提案”是不是忘了加链接了?
    musi
        2
    musi  
       2023-12-03 15:18:50 +08:00 via iPhone
    很新?不就是 iframe + proxy ?这不是现在微前端主流沙箱隔离方案?
    musi
        3
    musi  
       2023-12-03 15:21:17 +08:00 via iPhone
    另外这种隔离方案防君子不防小人,沙箱逃逸方案简直不要太多
    musi
        4
    musi  
       2023-12-03 15:22:12 +08:00 via iPhone
    忘了说了,现在 shadowRealm 的 polyfill 也是这种实现
    shendaowu
        5
    shendaowu  
       2023-12-03 20:40:45 +08:00
    @musi 问一下大佬未来 JavaScript 标准中会有能防小人的比较安全的类似沙箱的东西吗?会有的话大概还要等几年?
    musi
        6
    musi  
       2023-12-04 08:55:28 +08:00   ❤️ 1
    @shendaowu 到目前为止 js 提案中还没有那种稍微安全的 API 出现,另外值得一提的是,这种提案涉及到底层,必须由浏览器底层去适配,由 JS 自己去实现是不现实的。而每个浏览器由自己的安全模型,比如 Chrome 。之前 Chrome 也说了下内部对于 shadowrealm 的讨论,有兴趣可以看看这里 https://github.com/tc39/notes/blob/main/meetings/2021-01/jan-26.md#realms-update
    linwuhi
        7
    linwuhi  
       2023-12-04 17:15:34 +08:00
    很不错
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2745 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 32ms · UTC 02:12 · PVG 10:12 · LAX 18:12 · JFK 21:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.