Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

What is the state of JavaScript sandboxing these days?

I would like to build a site geared towards this kind of algorithmic art. Where one can paste the JS code snippets and see the resulting image. Similar to my html editor with instant preview:

https://github.com/no-gravity/html_editor

But with the ability to link to the code.

Is it feasible these days to build something like this, but without the ability of the code to jump out of the result frame? Like no external http requests, no fiddling with the window etc?



If you were not worried about preventing external requests and were okay with it being able to make requests as an arbitrary webpage unrelated to your site could if opened, then loading the code in an iframe with the sandbox="allow-scripts" attribute is enough.

If you needed tighter sandboxing than that, then I think WebAssembly is your best bet because you can control exactly what APIs are exposed to a WebAssembly module. You could then let users submit WebAssembly modules or let them submit JS that will be run in a JS interpreter running in WebAssembly. I think https://github.com/justjake/quickjs-emscripten or https://github.com/fermyon/StarlingMonkey (used by https://github.com/bytecodealliance/ComponentizeJS) look good for that.


Wow, sandbox="allow-scripts" looks pretty good. Doing some additional research, it seems one can disallow all network requests via Content-Security-Policy directives:

    <iframe sandbox="allow-scripts"></iframe>

    <script>
        document.querySelector('iframe').srcdoc=`
            <meta http-equiv="Content-Security-Policy" content="default-src 'none'; script-src 'unsafe-inline'">
            <span>Hello</span>
            <script>
                document.querySelector('span').innerHTML+=" world"; 
                fetch('/');
            </sc`+`ript>
            <img src='https://placecats.com/300/200'>
        `;
    </script>
The JS runs, but no network requests are made. I wonder if that solves all headaches regarding the execution of user provided JS code?


Oh I hadn't thought of using CSP for that. CSP alone used to not be enough but combined with the iframe's sandbox attribute (or the relatively newer sandbox CSP directives, which both block navigation and form submissions by default) then I think it's enough to block external network requests. This combo seems like a good solution for many use-cases.

However there are certain things that it still doesn't protect against: CPU and memory exhaustion. Someone's script can hog those resources and possibly cause the browser to crash the tab. If you only execute one user's code at a time when a user of the site specifically browses to it / activates it, then it might be acceptable because a user can learn to not re-activate code that just crashed their tab and won't be missing out on anything else, but if you had a setup where it didn't take user action to run other users' code (like you have a homepage that automatically shows a running preview of other people's code, or you have a multiplayer programming game where each player submits code and everyone in the game sees it run together and interact with other players' code) then it could be purposefully griefed by players submitting code that exhausts resources. If you need to protect against local denial of service attacks like this, or if you needed strict determinism for some reason, then I think a WASM-based solution is still the way to go.





Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: