[RndTbl] X11 forwarding through SSH after su/sudo

Adam Thompson athompso at athompso.net
Thu Jan 22 19:49:42 CST 2015

Turns out, at least on RHEL/Centos-style systems, if you run su(1) or 
sudo(8) after ssh'ing into a system, you can't run X11 apps from the 
su{do}'d user because of the way SSH handles X authentication there - it 
puts the Xauth cookie into the .Xauthority file instead of an 
environment variable.
I'm seeing references that Ubuntu & Debian don't behave like this, but 
don't have a live system to confirm.  I vaguely recall HPUX not behaving 
like this, and I don't care enough to test on *BSD right now.

Since I regularly need to su/sudo to another identity on a remote CentOS 
system, and it's a shared system, I don't want to gratuitously grant 
wide-open connection to my local X display; I at least want to limit the 
window of vulnerability... it doesn't look like I can eliminate it entirely.
Here's the best work-around I could come up with.
I think it manages to avoid exposing the Xauth data or anything else, 
but potentially requires you to enter your password more than once if 
sudo(8)'s cache has expired.
It also allows someone else su'd into that userid *at the same time as 
me* to access my Xauth cookies, but that's an acceptable window of risk 
for me since the cookie becomes invalid after I disconnect the SSH 
session.  Plus, I'm not the only person with root, so that vulnerability 
exists no matter what :).

> #!/bin/sh -e
> U=someuserid
> D=${DISPLAY/*:}
> E="$(hostname)/unix:${D%.0}"
> xauth extract - "$E" | sudo -u "$U" -- xauth merge -
> if [ -z "$*" ]; then
>         sudo -u "$U" -i
> else
>         sudo -u "$U" -- "$@"
> fi
> sudo -u "$U" -- xauth remove "$E"

Unfortunately, ssh(1)/sshd(8) sets DISPLAY to something like 
localhost:NN.0, but xauth has it recorded internally as FQDN/unix:NN ... 
these two $DISPLAYs are equivalent, but don't parse the same way on the 
command-line, hence the ugly manipulation.  I think this chunk of code 
is safe from obvious exploits (or errors), but dissenting opinions are 

N.B. long-time shell users will cringe at seeing $* instead of $@, but 
it turns out to be correct in this case: $@ *doesn't work* there.  The 
reason why is left as an exercise for the reader :-).

-Adam Thompson
  athompso at athompso.net

More information about the Roundtable mailing list