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).
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.
Make sure to run the server with the following setting in the httpd.conf file:
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.
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.
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).
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: