It is hard to confine untrusted software to just the stuff it is supposed to do. Server processes can be run as unprivileged users, chrooted or jailed in their own namespaces. If the software has to display something on the user's X11 however, different measures have to be taken.

One approach is to run the program under surveillance of systrace. This is good, but the code must have access to the X server and could try to grab/inject XEvents.

The following script (download) opens a nested X server (Xnest) and starts an xterm on it, running as another user. Starting from there, the user at the display can start a window manager and the suspicious software itself.

The programs inside the nested X cannot access the surrounding X display. With restrictive file permission on the regular user's homedir and standard precautions about the other user's account, this could protect against a few attacks.

# xsandbox username
# Start a nested XServer on display :1 and
# start processes in that Server as
# another user. Aim is to avoid grabbing
# of XEvents by untrusted programs which
# can be restricted to the nested display
# Requires sudo

function die {
	echo $1
	exit 1

devrandom=/dev/arandom	# Replace with your favourite PRNG if necessary

if [ -z $user ]; then
	die "Please give a username"

umask 0022

# Make two xauthority files, one for the user starting
# the script, the other as $user who will run inside the
# display.
xauth_you=`mktemp "/tmp/xauth.you.XXX"` || die "could not mktemp"
xauth_other=`sudo -u $user mktemp "/tmp/xauth.$user.XXX"` || \
	die "could not mktemp as $user"
x1=`dd if=$devrandom bs=32 count=1 2>/dev/null | sha1`
x2=`dd if=$devrandom bs=32 count=1 2>/dev/null | sha1`
cookie=`echo $x1$x2|cut -c-64`

# Clean up when finished
trap 'rm -f $xauth_you; sudo -u $user rm -f $xauth_other' EXIT INT

# Create auth cookie for display :1.0
xauth -i -f $xauth_you add :1.0 . $cookie || \
	die "could not create $xauth_you"

# Transfer authority to $user
xauth -i -f $xauth_you nextract - :1.0 | \
sudo -u $user xauth -f $xauth_other nmerge -  || \
die "Could not transfer authorization to $user"

# Start Xnest
Xnest :1 -auth $xauth_you -sss 2>1 1> /dev/null & xnest_pid=$!

# Start xterm as $user inside the Xnest
sudo -u $user sh -lc "export XAUTHORITY=$xauth_other; \
	/usr/X11R6/bin/xterm -display :1.0"

# Kill the Xnest when finished
kill $xnest_pid

Wed, 16 Nov 2005
[/projects] permanent link