Best practices for secure script programming

Small Wonders

Stricter Execution Verification

Shell scripts are intended for non-programmers to speed up common tasks in their daily lives on Unix operating systems. As a courtesy to this group of users, virtually all shells are set to be "permissive": In case of an error, they try to continue executing the script. This approach, which is quite friendly for a less technically experienced user, is critical because ambiguities that cause security problems do not stop the execution of the script.

The previously mentioned problem of destroying files would not have occurred with the following shell setting:

#!/bin/bash
set -o nounset
TAMS_VAR="wrongval"
echo /bin/${ENV}_VAR

When called with the -o parameter, the set command activates execution options that influence the runtime behavior of the interpreter. The nounset option used here considers unset variables to be errors. Execution of the shell script shown before now fails with the error shown in Figure 4.

Figure 4: The nounset option terminates program execution if it encounters missing variables.

The set -o errexit command terminates a program if a command called by the shell script does not return a value of zero. Its use can be checked by copying a non-existent file:

#!/bin/bash
set -o errexit
cp "doesnotexist" "tree.txt"
echo "Successfully copied"

The cp command does not return zero if it fails to find a parameter, which is why the status message passed to echo does not appear at the command line.

In scripts, you will always run into situations in which some of the code to be executed is non-critical, and the commands specified by -o can be disabled by calling +o. In the following script, the errexit option is no longer active when the copy command is processed:

#!/bin/bash
set -o errexit
set +o errexit
cp "doesnotexist" "tree.txt"
echo "Succesfully copied"

A problem can occur when processing commands connected by a pipe. Normally, this kind of command only fails if the last command in the pipe sequence does not return a value of zero. If you want errors somewhere in the hierarchy to cause a termination, then enable the pipefail option with the command set -o pipefail.

Changes to Global Variables

Another unintended result of lax language syntax is that variables defined in subfunctions develop unexpected side effects. As an example, look at a script that uses the variable o both inside and outside a function:

#!/bin/bash
hello_world () {
   o=2
   echo 'hello, world'
}
o=1
echo $o
hello_world
echo $o

Developers who grew up with other scripting languages would expect both calls to echo $o to return the value 1 . This is not inherently the case; the changes made in the function remain valid even after they have been executed. To fix the problem, you just need to tag the variables in the function with the local keyword:

#!/bin/bash
hello_world () {
   local o=2
   echo 'hello, world'
}
o=1
echo $o
hello_world
echo $o

Although longer shell scripts are not necessarily recommended for maintenance reasons, you should always protect variables used in functions with the local keyword. A colleague that recycles shell code at some point will be better protected from unexpected side effects.

ShellCheck

C and C++ programmers have used static analysis to check the results of their work for a long time. A static analysis tool has a knowledge base in which it stores programming errors that it checks against the code at hand. A similar tool for shell scripts is available with ShellCheck [6]. The tool, licensed under the GPLv3, behaves much like lint in terms of syntax: It expects the name of the shell file as a parameter, which it then checks for dodgy elements.

ShellCheck doesn't only look for security-relevant errors. In a list of ShellCheck checks available online [7], four dozen test criteria also identify and complain about general programming errors. Last but not least, a web version of the tool [8] checks scripts for correctness and security without a local installation.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy ADMIN Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

comments powered by Disqus
Subscribe to our ADMIN Newsletters
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs



Support Our Work

ADMIN content is made possible with support from readers like you. Please consider contributing when you've found an article to be beneficial.

Learn More”>
	</a>

<hr>		    
			</div>
		    		</div>

		<div class=