An Introduction to CGI - The Common Gateway Interface
by Jay Eckles
Security
A prerequisite for writing CGI programs is a thorough reading of
Lincoln Stein's WWW Security FAQ, located at
http://www.w3.org/Security/Faq/www-security-faq.html, as well as a good
long talk with your system administrator. Other resources that discuss
CGI security are
Security is an important topic when dealing with CGI programming. CGI
allows an anonymous user to execute a program on your system. This
obviously is not an inherently safe thing to do, so there are some
precautions that you need to take.
When writing CGI gateway programs, you should keep the following two
principals in mind:
- the user won't enter the input you expect
- never give a user more information than you have to
You can never assume that the input to your gateway program will have
the values or format that you expect. If you allow the gateway program
to write to disk or if the program makes any system call, you need to
make sure that the information written is not some sort of malicious
script or virus. The easiest, most effective, and best way to do this is
to determine what is acceptable input to your gateway program.
You should then write a function that examines the decoded query string
and removes any characters that you have not deemed safe. Generally safe
characters are alphanumeric characters and whitespace characters.
Generally unsafe characters are any character that could be considered
"shell metacharacters". These are characters that are used in scripts to
delimit commands, perform system calls, etc. An example of a
metacharacter is the backtick (`). In Perl, it can be used to
call system functions!
Here's a list of shell metacharacters:
; < > * | ` & $ ! # ( ) [ ] : ' " { }
While I have given you a list of metacharacters, you should not
implement your security by searching for these characters and deleting
them; rather, you should determine you list of safe characters, such as
an array containing all the upper and lower case letters a-z and the ten
digits. You should then check your input against this list, and delete
anything that does not appear in your "safe list". This way you
explicitly avoid any character that might be damaging even though you
were not aware of the risk it poses.
If you are writing a program like a guestbook, you might not want to
prevent your users from using these characters in their entries; some of
them are punctuation marks required for proper grammar. The solution is
to escape the characters in your program. You should have a function
that checks the input, looking at each character; if the character is a
metacharacter (or, even better, if it's not a safe character), escape it
by preceding it with a backslash (\). Again, though, you should
define your safe list of characters, but in addition to this list,
define a list of acceptable characters to escape. Then check the input
against the safe list - if a character is not in the safe list, determine
if it is in the list of acceptable characters to escape. If it is,
escape it, and if it is not, delete it. In Perl and some other
languages this can be done easily with a regular expression. In other
languages like C, you need to take the time to develop a function that
looks at each character individually and deals with it. Some CGI
libraries and modules may already have a function to perform this
checking - see the documentation to find out for sure.
When writing a gateway program, you should take care not to
intentionally or unintentionally leak information about the host
machine. Doing so provides information that can help malicious users
discover ways to attack the system. Along the same lines, you should
take care to make sure that the source of your program is not available
for casual viewing. The more a user knows about your program and the way
it works, the more likely he or she is to discover security bugs in it.
It is, of course, impossible to conceal the source of scripts that you
get from CGI archives or for scripts that you distribute from your own
site, but you can help this situation by simply renaming the program
before you use it. For example, if you a popular CGI program, rename it
"myprog" or "mailit" or something not normally associated with the
popular title. This is a simple step but one that might keep a hacker
from bothering to get a copy of the popular source and finding bugs in
it.
Another step you should take in making your CGI gateway programs more
secure is turning off SSI in any directory where your program will write
to disk, especially if it writes to an html file. This will prevent the
user from tricking your script into including an SSI that could call a
malicious script or series of commands.
Yet another thing you can do is perform thorough error checking in
your program. You should not leave buffer sizes unchecked, you should
not leave type conversions unchecked, you should not leave input
unchecked for validity, etc. Doing so leaves you vulnerable to potential
security threats.
The basic philosophy that you must adopt is that you will not receive
the input you expect, all requests are attempts to compromise the
system, and you haven't thought of everything. You must realize that
you always run the risk of opening a security hole when you make your
network or computer accessible to the outside world by running an HTTP
server, so you must be prepared to pay the consequences of a security
breach. That means that before running a CGI gateway program on your
computer, network, or account, you should have everything backed up, and
back it up regularly.
[Contents] [Next] [Previous]
If you have any questions or would like to contact me for any reason, please email me at j.eckles@computer.org.
|