Any service open to the Internet at large must take security into
account. Large, complex software tends to expose subtle
vulnerabilities that attackers can exploit to gain unauthorized
access to the server host. Third-party modules or libraries can also
contain similarly exploitable bugs. Perl scripts
aren't immune either: incorrect untainting and
sanitizing of user input can lead to disaster when this input is fed
to the open( ) or system( )
functions.
Also, if the same mod_perl server is shared by more than one user,
you may need to protect users of the server from each other (see
Appendix C).
4.10.1. Using Only Absolutely Necessary Components
The more modules you have enabled in your web
server, the more complex the code and interaction between these
modules will be. The more complex the code in your web server, the
more chances for bugs there are. The more chances for bugs, the more
chance there is that some of those bugs may involve security holes.
Before you put the server into production, review the server setup
and disable any unused modules. As time goes by, the server
enviroment may change and some modules may not be used anymore. Do
periodical revisions of your setups and disable modules that
aren't in use.
4.10.2. Taint Checking
Make sure to run the server with the following
setting in the httpd.conf file:
PerlTaintCheck On
As discussed in Chapter 6, taint checking
doesn't ensure that your code is completely safe
from external hacks, but it does force you to improve your code to
prevent many potential security problems.
4.10.3. Hiding Server Information
We
aren't completely sure why the default value
of the ServerTokens directive in Apache is
Full rather than Minimal. It
seems like Full is really useful only for
debugging purposes. A probable reason for using ServerTokens
Full is publicity: it means that Netcraft
(http://netcraft.com/) and other similar survey
services will count more Apache servers, which is good for all of us.
In general, though, you really want to reveal as little information
as possible to potential crackers.
Another approach is to modify the httpd sources
to not reveal any unwanted information, so that all responses return
an empty or phony Server: field.
Be aware, however, that there's no security by
obscurity (as the old saying goes). Any determined cracker will
eventually figure out what version of Apache is running and what
third-party modules are built in.
You can see what information is revealed by your server by telneting
to it and issuing some request. For example:
panic% telnet localhost 8080
Trying 127.0.0.1
Connected to localhost
Escape character is '^]'.
HEAD / HTTP/1.0
HTTP/1.1 200 OK
Date: Sun, 16 Apr 2000 11:06:25 GMT
Server: Apache/1.3.24 (Unix) mod_perl/1.26 mod_ssl/2.8.8 OpenSSL/0.9.6
[more lines snipped]
As you can see, a lot of information is revealed when
ServerTokens Full has been specified.
4.10.4. Making the mod_perl Server Inaccessible from the Outside
It is best not to expose mod_perl to the
outside world, as it creates a potential security risk by revealing
which modules you use and which operating system you are running your
web server on. In Chapter 12, we show how to make
mod_perl inaccessible directly from the outside by listening only to
the request coming from mod_proxy at the local host (127.0.0.1).
4.10.5. Protecting Private Status Locations
It's a good idea
to protect your various monitors,
such as /perl-status, by password. The less
information you provide for intruders, the harder it will be for them
to break in. (One of the biggest helps you can provide for these bad
guys is to show them all the scripts you use. If any of these are in
the public domain, they can grab the source of the script from the
Web, study it, and probably find a few or even many security holes in
it.)
Security by obscurity may help to wave away some of the
less-determined malicious fellas, but it doesn't
really work against a determined intruder. For example, consider the
old <Limit> container:
<Location /sys-monitor>
SetHandler perl-script
PerlHandler Apache::VMonitor
AuthUserFile /home/httpd/perl/.htpasswd
AuthGroupFile /dev/null
AuthName "Server Admin"
AuthType Basic
<Limit GET POST>
require user foo bar
</Limit>
</Location>
Use of the <Limit> container is a leftover
from NCSA server days that is still visible in many configuration
examples today. In Apache, it will limit the scope of the
require directive to the GET
and POST request methods. Use of another method
will bypass authentication. Since most scripts don't
bother checking the request method, content will be served to the
unauthenticated users.
For this reason, the
Limit directive generally should not be
used. Instead, use this secure configuration:
<Location /sys-monitor>
SetHandler perl-script
PerlHandler Apache::VMonitor
AuthUserFile /home/httpd/perl/.htpasswd
AuthGroupFile /dev/null
AuthName "Server Admin"
AuthType Basic
require user foo bar
</Location>
The contents of the password file
(/home/httpd/perl/.htpasswd) are populated by
the htpasswd utility, which comes bundled with
Apache: