5 ms·
So their method of sandboxing Python code is to spin up a JS runtime (deno), run Pyodide on it, and then run the Python code in Pyodide. Seems a lot of work to
by behnamoh 2y ago
So their method of sandboxing Python code is to spin up a JS runtime (deno), run Pyodide on it, and then run the Python code in Pyodide.
Seems a lot of work to me. Is this really the best way to create and run Python sandboxes?
- kissgyorgy 2y agoNot at all.
- jononor 2y agoWhat is the best way? Or at least, a better way?
- babush 2y agoI recall Shopify having a seccomp-based jail to run untrusted ruby code. But their use-case was very limited so they can get away with blocking almost every syscall. Other than that... VMs? The fact that people consider JS/WASM engines good security sandboxes is a bit scary tbf.
- simonw 2y agoI trust a WASM sandbox a whole lot more than I trust a Docker container sandbox. WASM engines run in almost every browser on earth, billions of times a day. Security problems in those get spotted very quickly.
- babush 2y agoIt's a bit hard to do comparisons without going into threat models and all that _fun_ stuff :shrug: For example, JS runs in almost every browser on earth too, yet it took V8 devs 2 years to find out that `Math.expm1()` could return -0.0 (https://chromium.googlesource.com/v8/v8.git/+/56f7dda67fdc9777719f71225494033f03aecc96%5E%21/#F0 https://chromium.googlesource.com/v8/v8.git/+/56f7dda67fdc97...). This is a cherry-picked example, and JS is clearly more complex than WASM, but still. Just because stuff runs on a lot of devices doesn't mean it's more or less secure. Linux runs on quite a few devices too, yet we still find bugs, people still don't ship updates to said bugs, yadda yadda yadda. My point is just that lots of devs often skip the threat modeling and just think "I'll slap it in a WASM thingie an it'll be fine". Well good luck.
- kissgyorgy 2y agoLandlock, cgroups on Linux
- ehsanu1 2y agogVisor
- pansa2 2y agoIt might be. CPython doesn't support sandboxing Python code, so the only option is to run the whole interpreter within a sandbox.
- anentropic 2y agoIt's what ChatGPT does apparently... https://simonwillison.net/2024/Dec/10/chatgpt-canvas/ https://simonwillison.net/2024/Dec/10/chatgpt-canvas/
- simonw 2y agoNot exactly - ChatGPT has two ways it can run Python code. It can use Pyodide and run it directly in the user's browser (for Canvas), and it can also run Python code on one of their servers in a Jupyter environment in a locked-down Kubernetes container (their "Code Interpreter" tool). To my knowledge they don't yet have a run-Python-in-WASM-on-the-server implementation.
- jamestimmins 2y agoWhat’s the purpose of Jupyter here? Isn’t that optimized for notebooks, which presumably wouldn’t be relevant on the server?
- simonw 2y agoI think it's more about tapping into the Jupyter ecosystem of visualization libraries etc, plus the fact that there's lots of data analyst examples in the training data that come from notebooks.
- jamestimmins 2y agoThat's an interesting dynamic of the training data impacting the architecture. I wonder if this is a one-off or we see that in other areas as well.
- fzzzy 2y agoI think this is inevitable. Whatever is most highly represented (correctly) will become even more dominant.
- __mharrison__ 2y ago
- pseudosavant 2y agoIf there is a WASM build of the project, that is going to be the easiest and safest way to run that with untrusted user content. And Deno happens to be really good at hosting WASM itself. So, these are the two easiest tools to do this with. I was looking into using WASM in Python yesterday for some image processing. It requires pulling in a full WASM runtime like wasmtime. Still better than calling out to native binaries like ImageMagick, but definitely more complicated than doing it in Deno. If I was writing it myself I'd do Deno, but LLMs are so good at writing Python.
- kmangutov 2y agoInteresting to understand what is possible in this Deno/Pyodide environment. For example sklearn works despite being quite an involved dependency [1]. Another side to this is data input/output, which seems possible with a low level interface [2]. Very exciting that (a simple) end-to-end ML experience is now possible in the modern browser. [1] https://www.erp5.com/NXD-Blog.Scipy.and.Scikit.Learn.Compiled.To.WebAssembly.In.Pyodide https://www.erp5.com/NXD-Blog.Scipy.and.Scikit.Learn.Compile... [2] https://donatstudios.com/Read-User-Files-With-Go-WASM https://donatstudios.com/Read-User-Files-With-Go-WASM
- achierius 2y agoDefinitely not the safest: the safest way would be to spin up another VM. The hardware-level virtualization guarantees are much stronger than what any JS runtime could provide
- ridruejo 2y agoIt’s one of the best ways, at least on the sandboxing front. Hard to beat Wasm at that
- simonw 2y agoI've been trying to find a good option for this for ages. The Deno/Pyodide one is genuinely one of the top contenders: https://til.simonwillison.net/deno/pyodide-sandbox https://til.simonwillison.net/deno/pyodide-sandbox I'm hoping some day to find a recipe I really like for running Python code in a WASM container directly inside Python. Here's the closest I've got, using wasmtime: https://til.simonwillison.net/webassembly/python-in-a-wasm-sandbox https://til.simonwillison.net/webassembly/python-in-a-wasm-s...
- singularity2001 2y agoone wasmtime dependency and a self contained python file with 100 loc seems reasonable! much better than calling deno, at least if you have no pip dependencies... just had to update to new api: # store.add_fuel(fuel) store.set_fuel(fuel) fuel_consumed=fuel-store.get_fuel() and it works!! time to hello world: hello_wasm_python311.py 0.20s user 0.03s system 97% cpu 0.234 total
- lopuhin 2y agoit's pretty difficult to package native python dependencies for wasmtime or other wasi runtimes, e.g. lxml
- Already__Taken 2y agoyeh if you can't shove numpy in there its not really useful.
- antonvs 2y agoI was interested in how this compares in a kind of absolute sense. For comparison, an optimized C hello world program gave these results using `perf` on my Dell XPS 13 laptop: 0.000636230 seconds time elapsed 0.000759000 seconds user 0.000000000 seconds sys That's 36,800% faster. Hand-written assembly was very slightly slower. Using the standard library for output instead of a syscall brought it down to 20,900% faster. (Yes I used percentages to underscore how big the difference is. It's 368x and 209x respectively. That's huge.) Begrudgingly, here are the standard Python numbers: real 0m0.019s user 0m0.015s sys 0m0.004s About 1230% faster than the sandbox, i.e. 12.3x. About an order of magnitude, which is typical for these kinds of exercises.
- jjuliano 2y agoI am nowhere near as big or as popular as Pydantic, but this is my solution - https://kdeps.com/getting-started/resources/python.html https://kdeps.com/getting-started/resources/python.html
- redleader55 2y agoThe author states: > The code is executed using Pyodide in Deno and is therefore isolated from the rest of the operating system. To me personally, the premise is a bit naive - it assumes that deno's WASM VM doesn't have exploits, that pyodide doesn't have bugs, etc. It might as well ask the LLM to produce javascript code and run it under deno and then it would be simpler. In the end, the problem is one of risk budget. If you're running this in a VM you control and it's only you running your own prompts on it, maybe it's "good enough". If on the other hand, you want to sell this service to others who will attack your infrastructure, then no - it's not even close to be enough. Your question is a bit vague because it doesn't explain what "best way" means for you. Cheap, secure, implementable by a person over a weekend?
- fragmede 2y agoThe answer, I think, is to push running the VM back onto the user, and build on top of Fabrice's JS Linux and run the sandbox on the user's machine. That way at the very worst they can escape and steal their own cookies from the browser process the VM is running on/in.
- achierius 2y ago> premise is a bit naive - it assumes that deno's WASM VM doesn't have exploits, that pyodide doesn't have bugs, Eh, I wouldn't call this naive. Two points: 1. Pyodide bugs should not be a huge concern here. As long as your python code is executing on top of a JS runtime, the runtime is what matters first and foremost from a security pov. 2. Yes, it's possible for Deno to have bugs. But frankly: it's much less likely to than most any other method for doing this sort of sandboxing. Deno sits on v8, which is the engine used by Chrome, and there are very few applications in the world which have a closer eye and larger dedicated security budget than Chrome. V8 can have bugs, sure, but I would expect they (along with JSC and maybe SpiderMonkey) will have far fewer than any other runtime for a serious dynamic language on the market today. Yes, a VM would be better (and frankly, when you're talking about running Python on top of a JS runtime, might not even be less performance), but the reason why is not that they "have fewer bugs".
- kodablah 2y agoThere just aren't good Python sandboxing approaches. There are subinterpreters but they can slow to start from scratch. There are higher-level sandboxing approaches like microvms, but they have setup overhead and are not easy to use from inside Python. At Temporal, we required a sandbox but didn't have any security requirement, so we wrote it from scratch with eval/exec and a custom importer [0]. It is not a foolproof sandbox, but it does a good job at isolating state, intercepting and preventing illegal calls we don't like, and allowing some imports to "pass through" the outside instead of being reloaded for performance reasons. 0 - https://github.com/temporalio/sdk-python?tab=readme-ov-file#workflow-sandbox https://github.com/temporalio/sdk-python?tab=readme-ov-file#...
- achierius 2y agoOut of curiosity, why did you need a sandbox if you didn't have any security concerns?
- necovek 2y ago> but it does a good job at isolating state, intercepting and preventing illegal calls we don't like Sounds like they put the reason just there.
- kodablah 2y agoSibling quoted the proper part. It's to help people keep code deterministic by helping prevent shared state and prevent non-deterministic standard library calls.
- fzzzy 2y agoAt least we have subinterpreters now. Even if they are slow that is a really good thing.
- jacob019 2y agoIndeed. What ever happened to user mode linux?
- samuel 2y agoI spin up a docker container using the docker API. I haven't used gvisor because I don't expect the model to try kernel level exploits. If it were the case, we're already doomed.