Is it possible to run a bash script in a sort of sandbox?

Our product has a need to execute an unknown bash script on a delicate server in order to achieve a certain goal. This bash script is user-supplied. We are interested in ensuring that only specific commands are allowed, and that all other are not. Furthermore, we need to replace some commands with others.

So, for example, we would like to execute the script and allow the following commands: echo cat awk

But not allow any other command (we don't want to supply a specific list here).

Furthermore, if the script contains the command cp we would like to capture it and redirect to a different command (which can be done using alias).

Any idea how this is done?


The easiest way is to use a chroot jail containing only the commands you want the script to be able to run. You then run the script through a wrapper that calls chroot into the directory and then executes the script.


There is no 100% safe short of running the script inside a virtual machine, which would presumably prevent the script from achieving its goal. But there are two features that may help you. If you're worried that the script was written by a malicious person, these features are not enough; but if you're only worried that the script may do bad things to your system because it was written by a careless programmer or with different objectives in mind, either of these two features provides a decent sandboxing environment.

  • You can run a restricted shell by invoking bash as bash -r. I refer you to the bash manual for a detailed description; the basic idea is that the script cannot invoke commands that are not in $PATH, cannot change $PATH, cannot redirect to or from a file, and a few more restrictions. This is fairly simple to set up, but if the unknown script is too complicated for you to review, it's likely to use a lot of things that are forbidden in a restricted shell.

  • You can set up a chroot jail. The idea is to set up a directory tree /some/root and run the script in an environment that believes that /some/root is the whole filesystem (chroot is short for change root). Once the directory tree is set up, run the script (copied to /some/root/myscript) as chroot /some/root /bin/bash /myscript. For example, you would set up a directory /some/root/bin with the commands you want to allow, and the chrooted program would see this directory as /bin. You'll need to copy everything needed for the execution of the program inside the chroot: libraries, data files, bash, the script itself, etc. The script might need /proc mounted inside the chroot; you can do this with a command like mount -t proc proc /proc.

    If you need to make a whole directory tree available to the script, say /var/example, you have several choices. You could make a copy under /some/root. You could make hard links (if they work for your application and the chroot is in the same filesystem). On Linux, you can do mount --bind /var/example /some/root/var/example to “graft” /var/example inside the chroot. Note that a symbolic link can't work since the target of the link is determined inside the chroot.

    Note that chroot doesn't provide absolute security, particularly against processes running as root. For example, a root process could create a device file inside the chroot and access the whole disk through it. A chrooted process can still make network connections (you can forbid this by not including any networking program inside the chroot and ensuring that the untrusted program cannot create a file and make it executable or overwrite an existing executable).