Default Drupal, Apache, and PHP settings broadcast to hackers much more about your site's configuration than hackers should know. In this third article in a series, I review settings to tighten security and reduce this information leakage.
Table of Contents
- Reduce published software names and version numbers
- Minimize Apache server information in HTTP messages
- Disable or restrict Apache server information pages
- Restrict Apache server status pages
- Disable PHP information in HTTP messages
- Disable the Apache server signature
- Change the default name of the PHP session cookie
- Remove pages that display "phpinfo( )"
- Remove content that shouldn't be served
- Block Apache from serving its manual
- Move Drupal's text files
- Move Drupal's script files
- Move Drupal's "install.php"
- Remove extra entries from Drupal's "robots.txt"
- Hide revision control comments
- Remove Drupal's version number from "robots.txt"
- Remove Drupal's version numbers in CSS files or enable CSS aggregation
- Remove content that announces what software you use
- Remove "badge" images and configuration bragging
- Use a custom favicon instead of Drupal's favicon
- Use a custom logo image instead of Drupal's logo
- Disable error and debugging information
- Disable PHP on-page errors
- Disable Drupal's on-page errors
- Disable Drupal's devel module
- Disable Apache TRACE responses
- Further reading
This is part 3 in a series of web site security checklists. Part 1 reviewed Apache and Drupal settings to restrict access to files and directories, and Part 2 reviewed Drupal settings to control access to content in Drupal's database.
In a 2009 report (PDF), White Hat Security reports the top ten vulnerabilities in sites they tested. Number two, with a 47% likelihood, is Information Leakage. Vulnerabilities of this type come in many forms. They needn't just include obvious problems, like posting credit card and social security numbers to public pages. Other information leakage problems reveal information about the site's software and configuration, such as the model and version number of the software, host names, IP addresses, logins, and passwords.
Web masters often rely on "security through obscurity" — hoping that hackers won't notice security flaws. But today's hackers have automated attack tools that scan sites for vulnerabilities, poking at everything in the hope of finding a weakness to exploit. Relying on obscurity is not sufficient.
In this article I review more Apache, PHP, and Drupal settings you can use to reduce information leakage about the software and configuration you use. The less you tell hackers about your site's workings, the better.
Let me repeat from the first article:
- I do not discuss downloading or installing software or setting up directories, permissions, and chroot. How you do these is important, but beyond the scope of this article.
- I do not discuss basic Apache, PHP, MySQL, and Drupal configuration. I assume that you've already got things working and now you're ready to tighten security.
- This list is not exhaustive. No list could be.
- All of these settings have been tested, but test them yourself before using them on a production site. Every site is different.
Reduce published software names and version numbers
Don't tell hackers anything you don't have to. Disable everything you can that reveals the software you're using, its version numbers, and its configuration.
Minimize Apache server information in HTTP messages
Server: Apache/2.2.9 (Unix) PHP/5.2.6
Reduce this to the product name only by setting the "ServerTokens" directive in your "httpd.conf" file. In default Apache configurations, this is in "extra/httpd-default.conf".
This reduces the output to just:
Disable or restrict Apache server information pages
Apache's mod_info module can display a page listing your server's full configuration. It is often served at "http://YOURSITE/server-info". To disable it, look for a "SetHandler server-info" directive in a "<Location>" group in your configuration files and comment out the group. In default Apache configurations these directives are in "extra/httpd-info.conf" and included by "httpd.conf". Comment out the include directive to disable it all.
# Don't show server info #Include extra/httpd-info.conf
Alternatively, if you must have this information, then limit access to only trusted hosts by adding "Allow" directives.
# Allow access to server info from server and local network only <Location /server-info> SetHandler server-info Order allow,deny Allow from 127.0.0.1 # Localhost Allow from 192.168. # Local network (use your local IP range) </Location>
Restrict Apache server status pages
Apache's mod_status module can display a page listing all the running instances of the server and what they are doing right now. This list is often served at "http://YOURSITE/server-status". To disable it, look for a "SetHandler server-status" directive in a "<Location>" group in your configuration files and comment out the group. In default Apache configurations, these are in "extra/httpd-info.conf" and included by "httpd.conf". Comment out the include directive to disable it all.
# Don't show server status #Include extra/httpd-info.conf
Alternatively, if you need this information, then block access to it from anywhere except trusted hosts by adding "Allow" directives.
# Allow access to server status from server and local network only <Location /server-status> SetHandler server-status Order allow,deny Allow from 127.0.0.1 # Localhost Allow from 192.168. # Local network (use your local IP range) </Location>
Disable PHP information in HTTP messages
By default, PHP contributes its name and version number to Apache's "Server" field in every HTTP response. It also adds an "X-Powered-By" field and again includes the PHP version number. Here's a typical value:
Disable this by disabling "expose_php" in your "php.ini" file.
expose_php = Off
Disable the Apache server signature
By default, Apache includes information about the server and web master in its error pages. Disable this by disabling "ServerSignature" in your configuration files. In default Apache configurations this is in "extra/httpd-default.conf".
Change the default name of the PHP session cookie
PHP provides built-in management of a session cookie. This is used by Drupal, and a lot of other PHP code. Unless set explicitly, the cookie name is "PHPSESSID". Avoid advertising that you're using PHP by changing the default name to something generic, like "Session", by setting the "session.name" value in your "php.ini" file.
session.name = Session
Or set the value in your site's ".htaccess" file.
php_value session.name Session
Or set it for an individual Drupal site by adding it to "sites/YOURSITE/settings.php".
Remove pages that display "phpinfo( )"
PHP's "phpinfo" function shows detailed information about your PHP configuration. Never display this output on a public page. Scan your site's pages for the call, or use a search engine to look through your site for pages containing the function's output phrase "This program makes use of the Zend Scripting Language Engine" (include the double-quotes). You'd be surprised by how many public sites have this information published.
Remove content that shouldn't be served
Default distributions of Apache and Drupal include files there is no need to serve. When served, they can tell hackers exactly what software and versions you're using. Either block serving them, or move them to a private unserved directory.
Block Apache from serving its manual
Apache distributions include full documentation and an "extra/httpd-manual.conf" file that places that manual on-line at "http://YOURSITE/manual". Since the manual is on-line at Apache's site anyway, there is no need to serve it yourself, or indirectly tell hackers exactly what version of Apache you are using. Comment out the include directive for "httpd-manual.conf" in your "httpd.conf" file.
# Don't serve the Apache manual #Include extra/httpd-manual.conf
Move Drupal's text files
Drupal's installation includes helpful text files in the top-level directory, such as "INSTALL.txt", "UPGRADE.txt", and "CHANGELOG.txt". By default, all of these files are served at "http://YOURSITE/INSTALL.txt" et al. Nobody but you needs to see them, so move them to an unserved directory.
Move Drupal's script files
Drupal's top-level "scripts" directory contains optional shell and perl scripts that help clean up code or run Drupal's "cron.php" automatically. These scripts should never be served. Move the entire directory to an unserved directory. In fact, avoid ever having a directory with a name like "scripts" — it is a standard target for hacker scripts that probe a site. Other obvious targets are "cgi-bin", "bin", and "drupal". Watch your server logs and you'll soon see automated attacks trying these and other common directories.
Move Drupal's "install.php"
Drupal's "install.php" in the top-level directory is used once during the installation of Drupal. It is never used again, so there is no need to keep serving it. Move it to an unserved directory.
Remove extra entries from Drupal's "robots.txt"
Drupal's "robots.txt" file requests that search engines skip indexing certain files and directories. After you've moved the above text files and scripts out of the Drupal site directory, remove lines for them from "robots.txt". There is no need to advertise that the files ever existed.
One site security package I tested looks for "http://YOURSITE/update.php" to determine if a site is running Drupal. If found, it parses "http://YOURSITE/CHANGELOG.txt" to get the Drupal version number. Unfortunately, "update.php" does need to be served – but it doesn't have to be served to everybody. In part 1 of this article series I discussed ways to block access to this and other Drupal files.
Hide revision control comments
For added paranoia, remove revision control system comments added into served Drupal files. These comments give strong clues about the version of Drupal you're using.
Remove Drupal's version number from "robots.txt"
Drupal provides a "robots.txt" file for the site's top level directory. The first line of the file includes a revision control system comment and version number. Use a text editor and remove it.
Remove Drupal's version numbers in CSS files or enable CSS aggregation
Most of Drupal's CSS files include a revision control system comment that gives a version number. Either use a text editor to remove it, or enable CSS aggregation on Drupal's Administer > Site configuration > Performance page. CSS aggregation strips comments as it combines CSS files into one larger file.
Remove content that announces what software you use
While you can't remove all evidence of what server-side software you're using, you can be less obvious about it.
Remove "badge" images and configuration bragging
Image badges that declare loyalty to Drupal/MySQL/PHP/Apache/Linux/Mac OS X tell hackers how to attack. Remove the badges and any posts that brag about the site's server configuration.
Use a custom favicon instead of Drupal's favicon
Drupal's default configuration provides its own blue-water-drop favicon. Instead of advertising on every page that you are using Drupal, create your own favicon. Select the icon on Drupal's Administer > Site building > Themes pages.
Use a custom logo image instead of Drupal's logo
Drupal's default configuration also uses Drupal's own logo as your site logo for all themes. Change this to something more appropriate on Drupal's Administer > Site building > Themes pages.
Drupal's default icon is available at "http://YOURSITE/misc/durplicon.png", even if you don't use it as your site's logo. That makes it an easy way to test if your site is running Drupal. This file, and several other Drupal files should be served only when attached to pages at your site. I discuss ways to block access to these files in part 1 of this article series.
Disable error and debugging information
Avoid advertising software bugs and the inner workings of your site. Block error and debug messages.
Disable PHP on-page errors
By default, PHP errors print messages onto the web pages returned to users. Disable on-page error messages by unsetting "display_errors" and "display_startup_errors" in your "php.ini" file. Enable writing errors to your site's log instead by setting "log_errors" in your "php.ini" file.
display_errors = off display_startup_errors = off log_errors = on
If you do not have access to the host's "php.ini" file, then you can add similar lines to your ".htaccess" file:
php_flag display_errors off php_flag display_startup_errors off php_flag log_errors on
Or you can set them in "sites/YOURSITE/settings.php" for Drupal:
ini_set('display_errors', 'off'); ini_set('display_startup_errors', 'off'); ini_set('log_errors', 'on');
Disable Drupal's on-page errors
By default, Drupal errors are reported to Drupal's log and printed onto the offending web page. Disable Drupal's on-page error messages in Administer > Site configuration > Error reporting.
Disable Drupal's devel module
Drupal's devel module is useful during development. It displays the queries executed and memory used at the bottom of each page for all user roles with the "access devel information" permission. Before the site goes into production, either disable the module or disable the "access devel information" permission for all user roles. Disable the module on Drupal's Administer > Site building > Modules page or change its permissions on the Administer > User management > Access control page.
Disable Apache TRACE responses