Online Book Reader

Home Category

Classic Shell Scripting - Arnold Robbins [218]

By Root 1012 0
opens the door wide for "Trojan horses," described in Section 15.3.

Protect bin directories

Make sure that every directory in $PATH is writable only by its owner and by no one else. The same applies to all the programs in the bin directories.

Design before you code

Spend some time thinking about what you want to do and how to do it. Don't just type stuff in with a text editor and keep hacking until it seems to work. Include code to handle errors and failures gracefully.

Check all input arguments for validity

If you expect a number, verify that you got a number. Check that the number is in the correct range. Do the same thing for other kinds of data; the shell's pattern-matching facilities are particularly useful for this.

Check error codes from all commands that can return errors

Things you may not expect to fail might be mischievously forced to fail to cause the script to misbehave. For instance, it is possible to cause some commands to fail even as root if the argument is an NFS-mounted disk or a character-oriented device file.

Don't trust passed-in environment variables

Check and reset them to known values if they are used by subsequent commands (e.g., TZ, PATH, IFS, etc.). ksh93 automatically resets IFS to its default upon startup, ignoring whatever was in the environment, but many other shells don't. In all cases, it's an excellent idea to explicitly set PATH to contain just the system bin directories and IFS to space-tab-newline.

Start in a known place

Explicitly cd to a known directory when the script starts so that any subsequent relative pathnames are to a known location. Be sure that the cd succeeds:

cd app-dir || exit 1

Use full pathnames for commands

Do this so that you know which version you are getting, regardless of $PATH.

Use syslog(8) to keep an audit trail

Log the date and time of invocation, username, etc.; see the manual pages for logger(1). If you don't have logger, create a function to keep a log file:

logger( ) {

printf "%s\n" "$*" >> /var/adm/logsysfile

}

logger "Run by user " $(id -un) "($USER) at " $(/bin/date)

Always quote user input when using that input

E.g., "$1" and "$*". This prevents malicious user input from being further evaluated and executed.

Don't use eval on user input

Even after quoting user input, don't hand it to the shell to reprocess with eval. If the user reads your script and sees that it uses eval, it's easy to subvert the script into doing almost anything.

Quote the results of wildcard expansion

You can do several nasty things to a system administrator by creating files with spaces, semicolons, backquotes, and so on, in the filenames. If administrative scripts don't quote the filename arguments, the scripts can trash—or give away—the system.

Check user input for metacharacters

Look for metacharacters such as $ or ` (old-style command substitution) if using the input in an eval or $(...).

Test your code and read it critically

Look for assumptions and mistakes that can be exploited. Put yourself into a nasty mood, and read your code with the intent of trying to figure out how to subvert it. Then fix whatever problems you find.

Be aware of race conditions

If an attacker can execute arbitrary commands between any two commands in your script, will it compromise security? If so, find another way to do it.

Suspect symbolic links

When chmod-ing or editing a file, check it to be sure that it is a file and not a symbolic link to a critical system file. (Use [ -L file ] or [ -h file ] to test if file is a symbolic link.)

Have someone else review your code for mistakes

Often a fresh pair of eyes can spot things that the original author of a program missed.

Use setgid rather than setuid, if possible

These terms are discussed later in this chapter. In brief, by using setgid, you restrict the amount of damage that can be done to the group that is compromised.

Use a new user rather than root

If you must use setuid to access a group of files, consider making a new, non-root user for that purpose, and setuid

Return Main Page Previous Page Next Page

®Online Book Reader