What is Supple?

Supple is a tool for sandboxing untrusted code and providing security partitioning. It deliberately operates by first forking a subprocess which is strictly limited in what it can do. For example, only the Supple Lua modules may be loaded, and they are all loaded before any untrusted code is run. The developer interfacing with Supple in their project is responsible for ensuring that any functions/objects passed into the subprocess cannot break the sandbox in ways the project author did not intend.

For example, if you you're passing a file handle across, it's probably best if it's read-only. If you have an object representing a lot of sensitive stuff, it's probably best to have a proxy object in the host which acts as a security guard only allowing the sandbox to call pre-approved methods and access pre-approved data.

In order to support the above while still reducing the chance of anything breaking the sandbox, Supple always presents remote objects as userdata and forces the use of a file descriptor in order to allow calls back and forth between the two ends of the sandbox connection. This means that, for example, methods can be called and passed callback functions which can thread back and forth with only a strict nesting requirement.

Supple can also be asked to soft-limit the Lua VM opcodes and/or memory in-use-by-lua more tightly than the hard process limits compiled into Supple.

What does Supple depend on?

Lua 5.1 (5.2 may work but is untested) is a must. Supple also uses luxio.

So, how isolated is Supple's sandbox?

Summary of Supple's isolation system:

  1. Your "untrusted" code is run inside a Lua sandbox which has only a limited set of Lua's functionality exposed to it.
  2. That sandbox is soft-limited (optionally) in terms of VM opcodes and memory allocated by Lua
  3. The sandbox is run inside a monitoring Lua VM instance which is responsible for carefully marshalling calls etc into and out of the sandbox. All your comms go via this monitor.
  4. The monitor is, itself, a Lua VM anyway, inside a process which is separate from the process you're doing untrusted work on behalf of.
  5. The sandbox process is created using a rootly helper so that it's put into an isolation state consisting of a directory which is owned by root which is set as your root via the chroot call, but which is also rmdir'd so it's ephemeral. Your process drops privileges back to the calling UID so it cannot do anything inside its CWD anyway.
  6. On top of that, the sandbox has some pretty solid rlimits set in terms of max CPU usage, max VM size, max FDs open, and max size of any file it writes. As such, it can't create > 0 byte files in the directory it doesn't have access to, and could only do that if it closed the FD to the host process which is its only communications avenue.
  7. Then, if you're on Linux, we go one step further and pre-allocate enough memory for the interpreter to not hit the rlimit and then enter seccomp mode 1 which limits the syscalls permissible to read, write, _exit and sigreturn so even if you could have circumvented any/all of the limits above, you now can't make syscalls to take advantage of them.

If that isn't sandbox enough, I don't know what is.

Of course, it all depends on the host process not exposing stupid/dangerous routines to the sandbox, but that's not my problem (yet) :-)

Releases

Thus-far there has been no release of Supple.