Quantcast
Channel: User Kamil Maciorowski - Super User
Viewing all articles
Browse latest Browse all 651

Answer by Kamil Maciorowski for Require bash script to be run with sudo (not as root user)?

$
0
0

UID and EUID variables are initialized by Bash at shell startup, but my tests indicate that if they are already in the environment then they will not be changed. The output of id -ru and id -u is reliable (unless id is counterfeit). See for yourself:

env UID=foo EUID=bar bash -c 'printf "UID: %s\nEUID: %s\nid -ru: %s\nid -u: %s\n" \"$UID"   "$EUID"  "$(id -ru)" "$(id -u)"'

Shells other than Bash may or may not set UID and EUID, so in general id is the right tool.

You designed your script to be run by sudo. Depending on the settings in the sudoers file (we will get to them), sudo may or may not pass the variables from the environment of the invoking user to the environment of the script. Any of these may or may not fool your script:

env UID=foo EUID=bar sudo /path/to/your_scriptsudo UID=foo EUID=bar /path/to/your_script

SUDO_USER and SUDO_UID are set by sudo itself. Values from the environment of sudo are always overwritten, so these attempts to fool the script won't fool it:

env SUDO_USER= sudo /path/to/your_scriptSUDO_USER= sudo /path/to/your_script

The following example explicitly tells sudo itself to set the variable empty and if it works (again, depending on sudoers) then it will fool the script:

sudo SUDO_USER= /path/to/your_script

In sudoers the easiest way to disallow users changing the variables while calling your script is to use NOSETENV, e.g.:

ALL ALL=(ALL) NOSETENV: /path/to/your_script

Note the line shall be after more general lines.

With NOSETENV and if the script is interpreted by Bash, the relevant variables available inside your script run with sudo should be reliable. Still there is no point in checking UID against EUID, because normally sudo sets both to the ID of the target user. The two IDs differ for setuid processes, so e.g. for sudo itself. You can make sudo keep the difference by specifying stay_setuid in sudoers, but (if set globally) this may have other consequences. There is no need, since you have reliable SUDO_USER and SUDO_UID which tell you the invoking user.

Now in your script you can test as follows:

  • Check if $EUID (or $(id -u) in general) expands to 0 or not, to tell if the script is elevated or not.
  • Check if $SUDO_UID (or $SUDO_USER) is not empty, to tell if there is sudo in play.
  • Check if $SUDO_UID expands to 0 or not, to tell if the invoking user is elevated or not. Alternatively check if $SUDO_USER expands to root or not, to tell if the invoking user is named root or not; but note the two tests are not equivalent.

Finally note that users may still fool your script:

  • The root user or anyone that can become root, or anyone that can use sudo to run arbitrary commands as root can run your script in arbitrary environment as root, so if they want to fool your script then they will. There is no point in protecting specifically the script against this, as such users can run anything as root anyway, so if they are irresponsible or rogue then it's a bigger problem.

  • If a user manages to run the script without sudo, he or she can run it without sudo in arbitrary environment (including PATH or LD_PRELOAD that changes the behavior of id), so the script may initially "think" it is elevated, run commands that don't require being elevated and fail at commands that require being elevated. Depending on what the script does, this may or may not lead to problems. In general a regular user can only hurt him- or herself, or resources he or she has write access to. Users can hurt themselves even without your script.

    It is not your job to protect users from themselves; and fooling your script takes deliberate effort, it is unlikely this will happen by accident; so if users hurt themselves by fooling your script, it will be at their own wish. But if you really want to make this difficult for them then make the script non-executable for general public (chmod o-x …) and even not readable for general public (chmod o-r …).


Viewing all articles
Browse latest Browse all 651

Trending Articles