Why shouldn't I use setuid shell scripts? (taken from here)

You shouldn't use them for a variety of reasons, mostly involving bugs in the Unix kernel. Here are a few of the more well known problems, some of which are fixed on more recent operating systems.

  1. If the script begins "#!/bin/sh" and a link (symbolic or otherwise) can be made to it with the name "-i", a setuid shell can be immediately obtained because the script will be invoked: "#!/bin/sh -i", ie: an interactive shell.

  2. Many kernels suffer from a race condition which can allow you to exchange the shellscript for another executable of your choice between the times that the newly exec()ed process goes setuid, and when the command interpreter gets started up. If you are persistent enough, in theory you could get the kernel to run any program you want.

  3. The IFS bug: the IFS shell variable contains a list of characters to be treated like whitespace by a shell when parsing command names. By changing the IFS variable to contain the "/" character, the command "/bin/true" becomes "bin true".

    All you need do is export the modified IFS variable, install a command called "bin" in your path, and run a setuid script which calls "/bin/true". Then "bin" will be executed whilst setuid.

If you really must write scripts to be setuid, either

  1. Put a setuid wrapper in "C" around the script, being very careful to reset IFS and PATH to something sensible before exec()ing the script. If your system has runtime linked libraries, consider the values of the LD_LIBRARY_PATH also.

  2. Use a scripting language like Perl which has a safe setuid facility, and is proactively rabid about security.

but really, it's safest not to use setuid scripts at all.