The third common security hole that every programmer should bear in mind involves using the shell to execute other programs.
Let's consider a dictionary server. This program is designed to accept connections via internet.
Each client sends a word, and the server tells it whether that is a valid English word.
$ grep -x word /usr/dict/words
The http://siber.cankaya.edu.tr/SystemsProgramming/cfiles/grep-dictionary.c program in Fig. 11.6 shows how you might try to code the part of the server that invokes grep:
Figure 11.6:
Search for a Word in the Dictionary.
Note that by calculating the number of characters we need and then allocating the buffer dynamically, we're sure to be safe from buffer overruns.
Unfortunately, the use of the system function is unsafe. This function invokes the standard system shell to run the command and then returns the exit value.
But what happens if a malicious hacker sends a "word" that is actually the following line or a similar string?
The same problem can arise with popen, which creates a pipe between the parent and child process but still uses the shell to run the command.
There are two ways to avoid these problems.
One is to use the exec family of functions instead of system or popen. That solution avoids the problem because characters that the shell treats specially (such as the semicolon in the previous command) are not treated specially when they appear in the argument list to an exec call.
The other alternative is to validate the string. In the dictionary server example, you would make sure that the word provided contains only alphabetic characters, using the isalpha function. If it doesn't contain any other characters, there's no way to trick the shell into executing a second command.