How does it work? Which WASM euntime does it use? Does it use a Python jnterpreter compiled to WASM?
https://github.com/mavdol/capsule
(From the article)
Appears to be CPython running inside of wasmtime
---
That is not save at all. You could always hijack builtin functions within untrusted code.
def untrusted_function():
original_map = map
def noisy_map(func, *iterables):
print(f"--- Log: map() called on {func.__name__} ---")
return original_map(func, *iterables)
globals()['map'] = noisy_mapI have been looking towards some kind of quick-start qemu option as a possibility, but the project will take a while.
If we want to isolate untrusted code at a very fine-grained level (like just a specific function), VMs can feel a bit heavy due to the overhead, complexity etc
@task(name="analyze_data", compute="MEDIUM", ram="512MB", timeout="30s", max_retries=1)
def analyze_data(dataset: list) -> dict:
# Your code runs safely in a Wasm sandbox
return {"processed": len(dataset), "status": "complete"}
This is fundamentally awkward in a language with as absurdly flexible a type system as Python. What if that list parameter contains objects that implement __getattr__? What if the output dict has an overridden __getattr__?Even defining semantics seems awkward, especially if one wants those semantics to simultaneously make sense and have any sort of clear security properties.
edit: a quick look at the source suggests that the output is deserialized JSON regardless of what the type signature says. That’s certainly one solution.
We stick to JSON to make sure we pass data, not behavior. It avoids all that complexity.
Long, long ago, there was "repy"[1][2]. (This is definitely included in the "none succeeded" bucket, FWIW.)
I’ve been building on that foundation: script runs in sandbox, all commands and file writes get captured, human-in-the-loop reviews the diff before anything executes. It’s not adversarial (block/contain) but collaborative (show intent, ask permission).
Different tradeoff than WASM or containers: lighter than VMs, cross-platform, and the user sees exactly what the agent wants to do before approving.
WIP, currently porting to PyPy 3.8 to unlock MacOS arm64 support: https://github.com/corv89/shannot
This is so true
petters•1d ago
No,no, Docker is not a sandbox for untrusted code.
mavdol04•1d ago
ottah•23h ago
s_ting765•1d ago
ashishb•1d ago
staticassertion•1d ago
That is to say, Docker is typically a security win because you get things like seccomp and user/DAC isolation "for free". That's great. That's a win. Typically exploitation requires a way to get execution in the environment plus a privilege escalation. The combination of those two things may be considered sufficient.
It is not sufficient for "I'm explicitly giving an attacker execution rights in this environment" because you remove the cost of "get execution in the environment" and the full burden is on the kernel, which is not very expensive to exploit.
ashishb•1d ago
Dockler is better for running arbitrary code compared to the direct `npm install <random-package>` that's common these days.
I moved to a Dockerized sandbox[1], and I feel much better now against such malicious packages.
staticassertion•1d ago
I also implemented `insanitybit/cargo-sandbox` using Docker but that doesn't mean I think `insanitybit/cargo-sandbox` is a sufficient barrier to arbitrary code execution, which is why I also had a hardened `cargo add` that looked for typosquatting of package names, and why I think package manager security in general needs to be improved.
You can and should feel better about running commands like that in a container, as I said - seccomp and DAC are security boundaries. I wouldn't say "you should feel good enough to run an open SSH server and publish it for anyone to use".
ashishb•1d ago
That's not the main attack vector. The attack vector is some random dependency that is used by a lot of popular packages, which you `npm install` indirectly.
staticassertion•1d ago
Again, it's great to run `npm` in a container. I do that too because it's the lowest effort solution I have available.
quotemstr•1d ago
It is literally that. When you write "npm install foo", npm will proceed to install the package called "foo" and then run its installation scripts. It's as if you'd run curl | bash. That npm install script can do literally anything your shell in your terminal can do.
It's not "somewhat close" to RCE. It is literally, exactly, fully, completely RCE delivered as a god damn service to which you connect over the internet.
staticassertion•1d ago
The reason I consider it different from "I'm opening SSH to the public, anyone can run a shell" is because the attack typically has to either be through a random package, which significantly reduces exposure, or through a compromised package, which requires an additional attack. Basically, somewhere along the way, something else had to go wrong if `npm install <x>` gives an attacker code execution, whereas "I'm giving a shell to the public" involves nothing else going wrong.
Running a command yourself that may include code you don't expect is not, to me, the same as arbitrary code execution. It often implies it but I don't consider those to be identical.
You can disagree with whether or not this meaningfully changes things (I don't feel strongly about it), but then I'd just point to "I don't think it's a sufficient barrier for either threat model but it's still an improvement".
That isn't to downplay the situation at all. Once again,
> that doesn't mean I think `insanitybit/cargo-sandbox` is a sufficient barrier to arbitrary code execution, which is why I also had a hardened `cargo add` that looked for typosquatting of package names, and why I think package manager security in general needs to be improved.
neoCrimeLabs•1d ago
Start here to help give you ideas for what to research:
https://linuxsecurity.com/features/what-is-a-container-escap...
ashishb•1d ago
Anything including GNU/Linux kernel can be broken with such security vulnerabilities.
This is not a weakness in the design of containers. `npm install`, on the other hand, is broken by design (due to post-install.
neoCrimeLabs•1d ago
Partially correct.
Many container escapes are also because the security of the underlying host, container runtime, or container itself was poorly or inconsistently implemented. This creates gaps that allow escapes from the container. There is a much larger potential for mistakes, creating a much larger attack surface. This is in addition to kernel vulnerabilities.
While you can implement effective hardening across all the layers, the potential for misconfiguration is still there, therefore there is still a large attack surface.
While a virtual host can be escaped from, the attack surface is much smaller, leaving less room for potential escapes.
This is why containers are considered riskier for a sandbox than a virtual host. Which one you use, and why, really should depend on your use case and threat model.
Sad to say it, a disappointing amount of people don't put much hardening into their container environments, including production k8s clusters. So it's much easier to say that a virtual host is better for sandboxing than containers, because many people are less likely to get it wrong.
ashishb•1d ago
Sure, so running `npm install` inside the container is no worse than `npm install` on my machine. And in most cases, it is much better.
neoCrimeLabs•1d ago
quotemstr•1d ago
If you look at the interface contract, both containers and VMs ought to be about equally secure! Nobody is an idiot for reading about the two concepts and arriving at this conclusion.
What you should have written is something about your belief that the inter-container, intra-kernel attacker surface is larger than the intra-hypervisor, inter-kernel attack surface and so it's less likely that someone will screw up implementing a hypervisor so as to open a security hole. I wouldn't agree with this position, but it would at least be defensible.
Instead, you pulled out the tired old "education yourself" trope. You compounded the error with the weasely "are considered" passive-voice construction that lets you present the superior security of VMs as a law of nature instead of your personal opinion.
In general, there's a lot of alpha in questioning supposedly established "facts" presented this way.
coppsilgold•1d ago
Also, you can use the runsc (gvisor) runtime for docker, if you are careful not to expose vulnerable protocols to the container there will be nothing escaping it with that runtime.
eyberg•1d ago
Not it is not. In fact many of the container escapes we see are because of bugs in the container runtimes themselves which can be quite different in their various implementations. CVE-2025-31133 was published 2? months ago and had nothing at all do with the kernel - just like many container escapes don't.
theamk•1d ago
I am not saying that you should never update the OS, but a lot of of those container escapes have severe restrictions and may not apply to your specific config.
coppsilgold•1d ago
Containers are a kernel technology for isolating and restricting resources for a process and its descendants. Once set up correctly, any escape is a kernel 0day.
For anyone who wants to understand what a container is I would recommend bubblewrap: https://github.com/containers/bubblewrap This is also what flatpak happens to use.
It should not take long to realize that you can set it up in ways that are secure and ways which allow the process inside to reach out in undesired ways. As runtimes go, it's as simple as it gets.
neoCrimeLabs•1d ago
A container escape can be caused by combinations of breakdowns in several layers:
- Kernel implementation - aka, a bug. It's rare, but it happens
- Kernel compile time options selected - This has become more rare, but it can happen
- Host OS misconfiguration - Can be a contributing factor to enabling escapes
- Container runtime vulnerability - A vulnerability in the runtime itself
- Container runtime misconfiguration - Was the runtime configured properly?
- Individual container runtime misconfiguration - Was the individual container configured to run securely?
- Individual Container build - what's in the container, and can be leveraged to attack the host
- Running container attack surface - What's the running container's attack surface
The last two are included to be complete, but in the case of the original article running untrusted python code makes them irrelevant in this circumstance.
My point you must consider the system as a whole to consider its overall attack surface and risk of compromise. There is a lot more that can go wrong to enable a container escape than you implied.
There are some people who are knowledgeable enough to ensure their containers are hardened at every level of the attack surface. Even then, how many are diligent enough to ensure that attention to detail every time? how many automate their configurations?
Most default configurations are not hardened as a compromise to enable usability. Most people who build containers do not consider hardening every possible attack surface. Many don't even know the basics. Most companies don't do a good job hardening their shared container environments - often as a compromise to be "faster".
So yeah, a properly set up container is hard to escape.
Not all containers are set up properly - I'd argue most are not.
ranger_danger•1d ago
theamk•1d ago
Out of those, only first one is actually exploitable in common setups.
CVE-2019-5736 requires either attacker-controlled image or "docker exec". This is not likely to be the case in the "untrusted python" use case, nor in many docker setups.
CVE-2022-0185 is blocked by seccomp filter in default installs, so as long as you don't give your containers --privileged flags, you are OK. (And if you do give this flag, the escape is trivial without any vulnerabilities)
neoCrimeLabs•1d ago
The kata-containers [1] runtime takes a container and runs it as a virtual host. It works with Docker, podman, k8s, etc.
It's a way to get the convenience of a container, but benefits of a virtual host.
This is not do-all-end-all, (there are more options), but this is a convenient one that is better than typical containers.
[1] - https://katacontainers.io/
maple3142•1d ago
staticassertion•1d ago
LPEs abound - unprivileged user ns was a whole gateway that was closed, io-uring was hot for a while, ebpf is another great target, and I'm sure more and more will be found every year as has been the case. Seccomp and unprivileged containers etc make a huge different to stomp out a lot of the attack surface, you can decide how comfortable you are with that though.
gruez•1d ago
I would expect major distributions to have embargoed CVE access specifically to prevent this issue.
staticassertion•1d ago
senko•1d ago
We live in a bizarre world where somehow "you need a hypervisor to be secure" and "to install this random piece of software, run curl | sudo bash" can live next to each other and both be treated seriously.