Wednesday, 24 May 2017

PWD-based privilege separation

I am often tempted to try out a random github project with:

# mkdir random-repo
# cd random-repo
# git clone http://github.com/random-dude/random-repo .
# ./configure && make
[...]
# emacs hack-on-something.cc
# make
However that is naive from a security standpoint. Makefiles can do just about everything to your workstation, e.g. steal your e-banking credentials from .config/chrome. So, I want sandboxing. And I want it in a way that fuses nicely with the workflow above.

Basing sandbox activation on my shell current working directory seems to work quite nicely. Consider the following:

# id -nu
clefru
# echo $PWD
/home/clefru/devel
# pwdjail-mkdir random-repo
# cd random-repo
$ id -nu
random-repo
$ echo $HOME
/home/clefru/devel/random-repo
$ git clone http://github.com/random-dude/random-repo .
$ ./configure && make
[...]
$ cd ..
# echo $PWD
/home/clefru/devel
# id -nu
clefru
# emacs random-repo/src/file.cc
[...]
Notice:
  • I use pwdjail-mkdir instead of mkdir.
  • Entering a subdir beneath /home/clefru/devel/random-repo enters the sandbox
  • Leaving /home/clefru/devel/random-repo leaves the sandbox
In a nutshell, the sandbox concept gets fused with your working directory. I found this to fit nicely with my established working habits, that is chdir-ing into a project directory when doing work there. Let's look at how this works under the hood.

pwdjail-mkdir creates a sandbox user with its home directory set to the directory it has just created. My shell has a hook within chpwd, that when changing into a (sub-)directory of a sandbox user's home directory, the hook spawns a sub-shell via sudo for that sandbox user. The sub-shell also has a hook within chpwd that quits the sub-shell when the sandbox directory is left via another cd. Before quitting though, the sub-shell records the cd target directory and passes it to the outer shell. The outer shell, that is still hanging within its chpwd hook, grabs this target directory and chdirs into it. This completes the illusion that all of this is transparent.

To clean things up, I use pwdjail's version of rm -Ir named pwdjail-rm-Ir, which also removes the sandbox user. Sharing files between the sandbox user and the master user is done by setting a default ACL on the sandbox home directory. I still get mixed file owners if I happen to create files from within the sandbox and create files from the outside, but luckily with Posix ACLs I don't need an explicit step to fix permissions if the other users happens to access a file.

Grab the code from http://github.com/clefru/pwdjail, run pwdjail-setup and you are good to go. I tested this only with zsh, so make sure you have that installed.