DevSecFlops

# source code sandboxing

In 2025, how easy is it for a developer to sandbox their program?

Sandboxing, in this case, is when a developer limits available system resources to a program from within its source code. A simple example is calling chroot(2) to change the root file-system to an empty directory so that the program cannot scribble into the root file-system.

int main(void) {
  /* Program has full file-system access. */
  chroot("/var/empty");
  chdir("/");
  /* File-system root re-rooted in /var/empty. */
  int fd = open("/etc/passwd", O_RDONLY);
  /* Tried to open /var/empty/etc/passwd... 🤭 */
}

Operating systems have come a long way since chroot(), and allow developers to limit resources far beyond just the file-system root. In this article, I'll survey the tools for sandboxing on modern Unix systems:

So in 2025, how can we limit a program to only already-open file descriptors (e.g., standard IO) and memory management—regular console activities—using these tools? If the running program tries to do anything else, it must be terminated or otherwise unable to acquire the requested resources (files, sockets, shared memory, etc.). By way of example:

This should succeed…
print("Hello, world! 👋")
This should fail…
from pathlib import Path
txt = Path(".profile").read_text()
This should also fail…
import http.client
connection = http.client.HTTPSConnection("www.bsd.lv")

Below is a table of sandbox tools, in a variety of language wrappings, and an example invocation of each effecting our desired constraints. Click the folder icon on the example, references, and notes. Examples readable on a normal mobile phone (<20 lines) have lines show in blue, barely readable (20–30 lines) in orange, and above in red. Deprecated sandboxes are so marked next to their names.

In the above, I don't include library helpers such as libseccomp, since they don't (much) change the cognitive overhead in reading the canonical documentation. Ultimately, any sandbox tool will be implemented in the kernel.

In the following, I plot the length of a tool's documentation (manpage) over the length of the example. Why the length of the manpage? It's the standard way developers interact with tool documentation; and in a way, measures the cognitive load required to understand and use the tool.

How hard is it to sandbox your source code?

This graphs the text length of references that must be read to understand the system to the number of lines in an example.

Systems easy to understand (short references) and implement (short source code) are grouped in the lower-left, while progressively more complicated systems are in the upper-right.

We can further clarify this data by grouping by operating systems and sandboxes. How hard it is to implement a sandbox in your environment of choice?

These are all trivial examples, and only demonstrate as much as Hello, world programs demonstrate a programming language. Let's refocus on a real world example taken both as a snapshot and as developed over time.

## case study

Let's use openssh-portable as a canonical example. OpenSSH is under tremendous pressure for its security. It has a number of source code sandboxes, including most of those mentioned in this survey. In general, these sandboxes will do little more than our examples—limit resources used to only communication over standard IO and to perform in-process duties (memory management, etc.). How do the lengths of source code (in lines) for each sandbox measure, with the collected references length for comparison?

Sources…

This only shows an instantaneous view of the system: part of the security of a system is its maintenance over time. How difficult is it to maintain the security implementations over time? In the following chart, I continue looking at openssh-portable, but extracting its commit history (via GitHub) over time for the specific files used for sandboxing.

This plots cumulative commit counts in the GitHub repository over time. Size of commits is not regarded—only the frequency. Subsystems that require significant maintenance will grow much more quickly than those with lighter maintenance burdens.

## survey

In this section, I survey real-world sandbox users in open source systems using one or more sandbox.

This is incomplete! Help make these charts more meaningful: if you've significantly contributed to a sandbox effort, please submit an attestation by a GitHub pull request. Thank you!

For in-house systems, I mined the FreeBSD and OpenBSD git repositories (specifically usr.bin and usr.sbin) for sandbox invocations, then looked up the earliest entry for a contributor.

For general open source, I drew from the results of Sandboxing Adoption in Open Source Ecosystems (see the thanks section), which in turn searched third-party software repositories for seccomp (Debian and Fedora) and pledge. I only included those systems that had a specific commit and author for adding the sandbox support.

Lastly, I used GitHub search for key functions used in sandboxing, in particular for Capsicum, seatbelt, and Landlock.

## findings

It's clear that OpenBSD's pledge has been massively successful in getting traction in open source, both within OpenBSD and for third-party systems. This is likely due both to how ports are maintained by OpenBSD developers and the ease at which systems can be extended with sandbox support. The documentation and reference examples are succinct and easy to digest.

Linux's seccomp is far more complicated: it has a seven-fold increase in reference complexity, and even more for source complexity, over OpenBSD and FreeBSD. Furthermore, the maintenance burden for seccomp, as illustrated by openssh-portable, is considerable. Landlock is a simpler Linux alternative, but it's still new.

FreeBSD's Capsicum has fairly good traction within FreeBSD. Like OpenBSD, its documentation and reference examples are easy to digest.

Ominously, Mac OS X has deprecated its source sandbox (seatbelt), as has Java by discontinuing the JSM.

## contributing

I'm starting this site to gain a full picture of the sandbox landscape in open systems. Having a list of possible combinations of languages, operating systems, and sandbox tools is a good start. And for that, if you have additions, please visit the GitHub page to add more examples.

More importantly, I want to know who is using these security systems, and where. Let's put together some numbers for how many systems in the wild really are protected, and start a conversation about why systems are more popular, and what we can do to raise the state of security on less-popular systems. You can easily add attestations to systems where you've contributed a security sandbox with a GitHub pull request.

## thank you!

For a scientific treatment of the subject, read Sandboxing Adoption in Open Source Ecosystems, Maysara Alhindi and Joseph Hallett, SESoS 2024. I'd like to thank the authors for making their data available for me to incorporate into the statistics.

I'd also like to thank Ed Maste (emaste), Florian Obser (fobser), and Damien Miller (djmdjm) for their input in the subject matter.