Show HN: Run unsafe user generated JavaScript in the browser

This page summarizes the projects mentioned and recommended in the original post on news.ycombinator.com

Our great sponsors
  • SurveyJS - Open-Source JSON Form Builder to Create Dynamic Forms Right in Your App
  • WorkOS - The modern identity platform for B2B SaaS
  • InfluxDB - Power Real-Time Data Analytics at Scale
  • SES-shim

    Endo is a distributed secure JavaScript sandbox, based on SES

  • There's a related proposal for Compartments and Module constructor is a prerequisite to that. A shim for the entire thing exists, with lockdown and Compartments isolating code:

    https://github.com/endojs/endo/tree/master/packages/ses

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

    It has usage already, eg. metamask snaps

  • workerbox

    A secure sandbox to execute untrusted user JavaScript, in a web browser, without any risk to your own domain/site/page.

  • It's a really good question, and I originally [0] actually had some code that would randomise the sub domain. You can still do this if you host it yourself.

    But I think it's probably not nessisary so long as your users are not using indexDB (or any other data storage on that domain), as there should be no other way for the web workers to communicate with each other.

    0. https://github.com/markwylde/workerbox/blob/master/lib/index...

  • SurveyJS

    Open-Source JSON Form Builder to Create Dynamic Forms Right in Your App. With SurveyJS form UI libraries, you can build and style forms in a fully-integrated drag & drop form builder, render them in your JS app, and store form submission data in any backend, inc. PHP, ASP.NET Core, and Node.js.

    SurveyJS logo
  • quickjs-emscripten

    Safely execute untrusted Javascript in your Javascript, and execute synchronous code that uses async functions

  • If you need to call into user-generated Javascript synchronously or have greater control over the sandbox environment, you can use WebAssembly to run a Javascript interpreter: https://github.com/justjake/quickjs-emscripten#quickjs-emscr...

    QuickJS in WebAssembly is much slower than your browser's native Javascript runtime, but possibly faster than async calls using postMessage. As an added bonus, it can make async functions in the host appear to be synchronous inside the sandbox using asyncify: https://emscripten.org/docs/porting/asyncify.html.

  • proposal-shadowrealm

    ECMAScript Proposal, specs, and reference implementation for Realms

  • The upcoming JavaScript Shadow Realms proposal looks like it solves a similar problem: https://github.com/tc39/proposal-shadowrealm/blob/main/expla...

  • jailed

    execute untrusted code with custom permissions

  • What advantages does workerbox have over existing solutions like jailed [1]?

    [1] https://github.com/asvd/jailed

  • I know the industry has moved on to We assembly, but I thought it might be worth mentioning that I just recently finished a personal project to compile an arbitrary NodeJS script in QuickJS and call the code from C - all* in a statically or dynamically linked library, no support files.

    In case anyone is interested in calling JS from old school C-supported languages, check it out: https://github.com/ijustlovemath/determine-basal-native

    It's specific to my application but could easily be reused with a few tweaks.

    * Mostly all, the last step is to store the ESM JS script text in an object file and link it in, which I'm still working on.

  • caja

    Discontinued Caja is a tool for safely embedding third party HTML, CSS and JavaScript in your website.

  • WorkOS

    The modern identity platform for B2B SaaS. The APIs are flexible and easy-to-use, supporting authentication, user identity, and complex enterprise features like SSO and SCIM provisioning.

    WorkOS logo
  • Pentive

    Collaborative Spaced Repetition

  • Nice, I'm building a plugin system for my webapp too! I gave up completely on security [0] though because my plugins want DOM access, and may possibly manipulate elements outside their specific control, so I was like "fuck it". Thankfully there's a clear difference between my webapp and website, so hopefully I'll be able to educate my users to not trust stuff on the app side. We'll see :|

    Separately, how are you thinking about designing your plugin system? I built a PoC here [1] that basically revolves around combining a DI container with the decorator pattern. We start with an initial default DI container/object, then that container is passed to a plugin which wraps certain methods or adds new ones. That new container is then passed to the next plugin which wraps it, etc, etc. Actual implementation is here [2]. The only thing that sucks about my design is that plugins must call `.bind(this)` when wrapping a method.

    0: https://github.com/AlexErrant/Pentive/blob/main/design-decis...

    1: https://github.com/AlexErrant/Pentive/blob/main/app/src/plug...

    2: https://github.com/AlexErrant/Pentive/blob/main/app/src/plug...

  • vm2-process

    Execute unsafe javascript code in a sandbox

  • There is vm2 [0] for nodejs, but if you look at the issues there are escapes found occasionally, even some this year. I think it's too risky to run untrusted code on node.

    You could run a headless chrome using puppeteer, then run workerbox. But it's probably too much overhead for a server app.

    Oh, if you're making a form builder, I have to recommend json-editor [1]. It's not mine and I haven't actually used it just (I've only found really recently), but basically you give a JSONSchema and it will make a form for you, with validations and conditionals all built in. Might come in useful.

    0. https://github.com/markwylde/vm2-process

  • json-editor

    JSON Schema Based Editor (by jdorn)

  • proposal-compartments

    Compartmentalization of host behavior hooks for JS

  • There's a related proposal for Compartments and Module constructor is a prerequisite to that. A shim for the entire thing exists, with lockdown and Compartments isolating code:

    https://github.com/endojs/endo/tree/master/packages/ses

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

    It has usage already, eg. metamask snaps

NOTE: The number of mentions on this list indicates mentions on common posts plus user suggested alternatives. Hence, a higher number means a more popular project.

Suggest a related project

Related posts