20

After much frustrating head-brick-wall contact, I've discovered this:

$ echo $PATH
/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/steve/bin

$ sudo bash
# echo $PATH
/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin

but

$ sudo bash -c 'echo $PATH'
/sbin:/bin:/usr/sbin:/usr/bin

$ sudo bash -Ec 'echo $PATH'
/sbin:/bin:/usr/sbin:/usr/bin

I gather from another post that the sudo path is read from /etc/sudoers — but why? Does setting $PATH in /root/.profile make any sense, or is that just a recipe for the confusion above (ie, spawning an actual shell causes a different $PATH from that used in casual sudo commands...)?

I'm using bash on RHEL 6.4.

0

3 Answers 3

16

Protections

sudo has builtin protections that you're noticing when you run several of these commands. These protections are doing a number of things, such as enforcing a safe $PATH.

From the /etc/sudoers file:

Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin

This is what's showing up when you run your sudo -c .... commands. You can disable this behavior with the -E switch to sudo.

NOTE: For some setups the -E switch will not work. To "workaround" it you can use sudo env "PATH=$PATH" bash. This will also carry your current $PATH forward to your sudo environment.

interactive vs. login

When you ran this command:

$ sudo bash

You ran a interactive bash shell vs. a login bash shell. This has to do with how bash sources it's configuration files.

  • interactive, aka bash or bash -i, sources $HOME/.bashrc
  • login, aka bash -l, sources $HOME/.bash_profile

So why doesn't -E work?

TylerRick's answer to this SO question (sudo changes PATH - why?) covers a lot of the reasons as to why. The main is that it's typically hardcoded when sudo is compiled, as is the case with Ubuntu, resulting in these switches as being useless. There have been long open issues in Launchpad regarding these and they've never been fixed, leaving us with the realization that Canonical thinks it's better to leave this behavior as the default.

2
  • Thanks for the PATH=$PATH workaround - which does work. Are you able to explain why -E doesn't work for "some setups"? Presumably because the PATH-resetting behaviour of sudo is activated after -E is applied? Commented Sep 23, 2013 at 0:32
  • @SteveBennett - see updates as to why.
    – slm
    Commented Sep 23, 2013 at 0:56
5

When a rule in sudoers authorizes a user to run a specific command wibble, it is often necessary to set PATH to a safe value: one that only contains directories where the user cannot plant his own programs. If wibble called the external command foo, and PATH was not reset, then the user could put ~/bin at the front of his PATH, link /bin/sh to ~/bin/foo and then run sudo wibble to invoke ~/bin/foo which lets him type arbitrary shell commands.

Resetting PATH is therefore a safe default. While it is not necessary in all cases, it is a lot easier and safer to make that the default setting.

When a rule in sudoers authorizes a user to run arbitrary commands, resetting PATH has no direct security advantage. There is an indirect advantage, which is that the user may accidentally have set a PATH containing potentially harmful programs, and resetting PATH avoids risking that these programs are called accidentally. There is also a functional advantage: it is common to need to have /usr/local/sbin, /usr/sbin and /sbin when running commands as root but not to have them as an ordinary user.

If you don't want the path to be reset when you run sudo, add yourself to the exempt group in sudoers:

Defaults exempt_group+=stevebennet

If you run a login shell (sudo -I or sudo bash -l or other method), that shell typically reads .profile in the target user's home directory, and that file may change PATH.

1

That's for security reasons. The PATH is set to a well defined one and not to whatever hacked PATH the source user might be having.

See https://superuser.com/questions/98686/passing-path-through-sudo for kind of a workaround.

Not the answer you're looking for? Browse other questions tagged .