XDG environment variables with substitute user

Peter Nowee peter.nowee at gmail.com
Tue May 19 07:04:09 PDT 2015


On 5/14/15, Simon McVittie <simon.mcvittie at collabora.co.uk> wrote:
> On 13/05/15 22:06, Peter Nowee wrote:
>> I was wondering what a substitute user application, like gksu, should
>> do with regard to XDG environment variables when launching an
>> application as another user?
>
> If a "substitute user" application like gksu does not pass environment
> variables through a *whitelist* - "only keep safe variables", not
> "delete unsafe variables" - then the invoking user can almost certainly
> execute arbitrary code as the target user.
>
> (For instance, consider LD_LIBRARY_PATH, LD_PRELOAD, BASH_ENV, ...)
>
> If the target user is granted access to the invoking user's X11 display
> (e.g. su to root preserving XAUTHORITY and DISPLAY), then they can
> likely also execute arbitrary code as the invoking user; they can
> certainly spy on keyboard input, take screenshots, and probably inject
> forged keyboard input too.
>
> On any halfway modern system I would recommend pkexec over gksu as the
> root-privilege-escalation tool of choice. It uses an environment
> whitelist. That means no DISPLAY (unless you explicitly include it in
> the invoked command - "pkexec env DISPLAY=$DISPLAY xterm"), hence no X11
> apps as root, but to be honest I think that's more feature than bug.

Ok, I see your point: It's safest not pass any environment variables
except those whitelisted, and pkexec does that. But I guess there is
no standard that says that all "substitute
user"/"root-privilege-escalation" programs should behave this way,
right?

I took some time to read some more and this is my understanding so far
(please correct me if I'm wrong):

With regard to gksu/su:
- gksu is just a graphical frontend to su, so behavior with regard to
environmental variables should be discussed in the context of su, not
gksu. (My mistake for not grasping this earlier.)
- For Linux, there are actually two versions of su: util-linux su and
shadow su (used in Debian). I tested the following using shadow su,
but it should be the same for util-linux su.
- The default behavior of su (without --login, -l, or -) leaves many
environment variables, including the XDG ones, of the invoking user
intact in the target user's environment.
- su option --login (or -l, or simply -) sets many environment
variables to what the target user would expect on login. On my system
that results in XDG environment variables being unset. One could
discuss if they should be set to those of the target user [1], but I
guess either way is better than keeping those of the invoking user.

With regard to "substitute user" programs in general:
- The above-mentioned discussion [1] exemplifies that many things
depend on historic behavior, and that there are many strong opinions
on what correct behavior with regard to environment variables should
be.
- I guess this dependence on historic behavior for each individual
"substitute user" program (su, runuser, sudo, pkexec, ...) explains
why there seems to be no standard prescribing a uniform behavior
between them, and why there will probably never be such a standard.

Back to the XDG environment variables:
- The XDG Base Directory Specification [2] does not seem to prescribe
that variables such as $XDG_CONFIG_HOME must be owned by the user.
- However, it does state that $XDG_RUNTIME_DIR MUST be owned by the user.
- Thus, using a "substitute user" program in a way that changes user
but keeps the invoking user's $XDG_RUNTIME_DIR already violates the
XDG Base Directory Specification. An example of this would be the use
of su without options.
- Unfortunately, as noted above, "substitute user" programs themselves
are not likely to change their historically defined behavior.
- Therefore, the person or program using the "substitute user" program
bears the responsibility of complying with the XDG Base Directory
Specification by ensuring that at least $XDG_RUNTIME_DIR, but better
all XDG environment variables, are cleared or changed to those of the
target user, for example by using the right program with the right
options (e.g. pkexec, su --login, ...), or by explicitly including the
environment in the invoked command (as in your example by using env).

Is this correct?

Thanks,
Peter

[1]: https://bugzilla.redhat.com/show_bug.cgi?id=753882 (pam_systemd
should not use loginuid (at least not when used by su))
[2]: http://standards.freedesktop.org/basedir-spec/latest/ar01s03.html


More information about the xdg mailing list