This question is totally general and not only applicable to my situation, but… I have a small busybox appliance where I want a non-root user to be able to execute a particular script with root priviliges. For example, something like this small script to enable DHCP, where the only variable (
$1) to send in on the cmdline (!!) is what host name to send out:
#!/bin/bash udhcpc -b -i eth0 -h $1
running udhcpc like this requires root access, so to do this I plan on modifying
/etc/sudoers to contain this line:
joe ALL = NOPASSWD: /path/to/enable_dhcp.sh
which should enable “joe” to easily run that script with root privileges by simply running:
and not being asked for a password (which is what I want, since I want joe to be able to script this).
Now.. I know (or at least think I do) that using
$1 in a script that can easily be run with root privileges is a HORRIBLE idea since you can inject whatever you want into that.
So… what is the best way to deal with this? How do I let joe do what I want with root privileges, allow him to pass in a variable (or effectively do so like with an environment variable), while not being wide open to injection attacks?
Running shell scripts under
sudo is safe provided that
sudo is configured to reset the environment. Conversely, if
sudo doesn’t reset the environment, then running a shell script is not safe, even if your script doesn’t use its parameters (see Allow setuid on shell scripts). Make sure that you have
Defaults env_reset in
/etc/sudoers or that this option is the compile-time default (
sudo sudo -V | grep env should include
Reset the environment to a default set of variables).
There is no particular danger in using the script parameters.
$1 is a string, all you need to make sure is that you’re using it as a string. (For example, don’t do
eval "$1".) Obviously, it’s especially important here not to make assumptions about the contents of the variable, and to put double quotes around all variable substitutions (i.e. write
$1). Note that putting double quotes around variable substitutions isn’t specific to scripts running with privileges, it’s something you must do all the time.
You may want to validate the parameter further, depending on what
udhcpc does with something that doesn’t look like a host name. For example, this will perform a first syntactic check:
#!/bin/sh case "$1" in *[!:-.0-9A-Za-z]*|-*) echo 1>&2 "Badly formed host name!"; exit 3;; esac udhcpc -b -i eth0 -h "$1"