> and there is your arbitrary python code execution - which is exactly what we don't want.
The state of userspace sandboxing across all operating systems I'm aware of is dismal. As a developer it should be trivial to spawn a process with a subset of the privileges of the parent process.
Linux is better than most in terms of options, but you have to understand seccomp, namespaces, cgroups, containers, capabilities, etc etc. It's too confusing. Why can't I just say "spawn this process, limit it to reading files in this directory, writing files in this directory, this socket, max 10GB disk space, max 5% CPU, max 10% memory"? I'd even settle for just being able to limit filesystem and network access.
Even if you do manage to make it work, since the APIs require SETUID executables you might actually be opening yourself up to a bigger risk.
Someone needs to pull a WireGuard and make a small, simple API for userspace sandboxing. And please somehow miraculously make it so it is likely to be implemented by Windows.
> The state of userspace sandboxing across all operating systems I'm aware of is dismal. As a developer it should be trivial to spawn a process with a subset of the privileges of the parent process.
It's a breeze on OpenBSD, at least as an application developer. The key is realizing that you can't effectively sandbox a process without the process cooperating. That often means refactoring the source code to reorganize how and when it acquires resources. If you're refactoring the source code, then in many cases it's easier and most effective for the process to sandbox itself, thus pledge(2) (https://man.openbsd.org/pledge.2) and unveil(2) (https://man.openbsd.org/unveil.2). Afterall, the process and its authors are the final and best arbiters of the resources it will need to initialize and acquire during runtime.
All the pain on Linux comes from people struggling to sandbox uncooperative processes (i.e. processes you can't modify and refactor) by trying to construct a fake environment. That's ultimately a losing battle. And quite ironic that people instinctively seek that route even in the context of open source applications where source code is readily available and upstreaming patches and improvements extremely common. OpenBSD has managed to sandbox to some extent almost every program, including command-line utilities, that ship with the OS. And they continue to incrementally improve the those sandboxes over time--IOW, pledge and unveil are amenable to iterative, steady development of capability management, rather than requiring herculean effort up front, potentially resulting brittle architectures that make feature additions excessively difficult.
While there's nothing quite as simple as pledge on Linux (seccomp is close but has several problematic caveats), something very similar to unveil was upstreamed into Linux last year: Landlock. See https://docs.kernel.org/security/landlock.html Unfortunately, AFAICT, Landlock, like seccomp, is mandatorily inherited on fork (no option to disable), which means it can be difficult to integrate into existing applications that might fork or exec other processes--they might be completely unrelated and require a privilege set that isn't a subset of the invoker. Reordering the sequence of process spawning to before the privilege drop can be impractical--effectively impossible if it means basically rewriting the entire program, for example with a read-eval loop (e.g. procmailrc). Spawning processes indirectly through, e.g., systemd or pkgexec, simply shifts the problem and can even increase exposure and bug risk. But for daemon services which are only leaves on the process tree, that's not a concern; Landlock and to a lesser extent seccomp can better approximate unveil and pledge, respectively.
I'm totally fine changing the way I write my applications to make them more secure. I just don't feel like the APIs are there.
Personally I think capability-based security models is the best idea I've seen so far. Set up the file descriptors and network sockets your program needs at startup, then drop any other privileges. The problem is file descriptors don't cover things like directory trees AFAIK.
If performance isn't critical, what are your thoughts on using QEMU to wrap an application for security purposes? That might even work on Windows.
Not sure. Even if it does, it's going to be built using the APIs I already mentioned, and therefore not available in userspace. It doesn't make any sense for a process to need special privileges in order to limit a child process to strictly lesser privileges.
Because I'm not a security expert. Gaining the knowledge necessary to do it well would probably require a specialization change and years of prep, which would be an inefficient division of labor. Plus, it's an interesting problem, but not one I'm particularly drawn to. I'm currently focused on solving other problems[0] higher up the stack.
The state of userspace sandboxing across all operating systems I'm aware of is dismal. As a developer it should be trivial to spawn a process with a subset of the privileges of the parent process.
Linux is better than most in terms of options, but you have to understand seccomp, namespaces, cgroups, containers, capabilities, etc etc. It's too confusing. Why can't I just say "spawn this process, limit it to reading files in this directory, writing files in this directory, this socket, max 10GB disk space, max 5% CPU, max 10% memory"? I'd even settle for just being able to limit filesystem and network access.
Even if you do manage to make it work, since the APIs require SETUID executables you might actually be opening yourself up to a bigger risk.
Someone needs to pull a WireGuard and make a small, simple API for userspace sandboxing. And please somehow miraculously make it so it is likely to be implemented by Windows.