Overview
The Apache Web server is currently the most frequently deployed Web server. After hearing about all the problems with Microsoft's Internet Information Server (IIS), you probably assume that Apache must be considerably easier to secure. This assumption is to some degree true---although Apache is by no means perfect from a security perspective, you will not have to do as many things to secure your Apache server(s). In fact, ensuring that scripts that run on your Web server are secure is likely to be your greatest challenge: creating secure scripts is a challenge, anyway, no matter what Web server you use. Still, you'll have to do some work to make Apache able to resist most attacks. These guidelines present the measures needed to achieve baseline security in Apache Web servers.
Six Major Areas To Be Aware Of When Securing Your Apache Server
To secure your Apache Web server, you’ll need to pay attention to six major areas:
- Obtaining as secure a version of Apache as possible
- Securing the underlying operating system
- Configuring your server correctly
- Running only the features and services that you genuinely need
- Ensuring that CGI or other scripts are written properly
- Ensuring that major vulnerabilities are patched
1. Obtaining as Secure a Version of Apache as Possible
If possible, obtain a secure version of Apache for the operating system on which Apache will run. The Red Hat Secure Server, which offers encrypted network sessions, is one of the best-known versions of Apache. If you have already installed Red Hat Linux without installing the secure server packages, you can use RPM, Gnome-RPM, or Kpackage to install the RPM packages included on the Red Hat Linux CD to install the secure server afterwards. Stronghold 3.0 is a secure Red Hat — based SSL Web server with 128-bit encryption. It also has a patch for vulnerabilities OpenSSL.
2. Securing the Underlying Operating System
Apache runs on Windows NT, Linux, and Unix.1 The first thing you need to do is ensure that the operating system on which any Apache Web server runs is secure. If you fail to secure the operating system, but make Apache as secure as possible, attackers will be able to exploit operating system vulnerabilities to successfully attack your Apache server. Security guidelines for the major operating systems used at the Lab are posted at https://commons.lbl.gov/display/cpp/CPP+Services.
3. Running Only the Features and Services that You Genuinely Need
The third thing you need to do is ensure that your Apache server runs only the features and services that are needed.
- Include Only Necessary Apache Modules When You Compile Apache
Before you compile the Apache code, it is important to carefully think about the types of functions your Web server is and is not supposed to perform. You’ll need to select the appropriate Apache modules to support the necessary functions, and then compile. This is critical for security, because the fewer the modules you include before you compile everything, the fewer services will run. Running a minimum set of services will in general greatly reduce your Web server’s susceptibility to attack! Additionally, some services are difficult to kill once you have compiled the modules that start them into Apache. - Install The mod_SSL Module
Encrypting the traffic between your Web server and Web browsers in the danger-filled Internet environment is a necessity, not a luxury. An excellent way to provide encryption is to install the Apache Interface to OpenSSL (mod_ssl) before you compile the Apache code. This module provides high-strength encryption for the Apache 1.3 Web server through the Secure Sockets Layer (SSL v2/v3) and Transport Layer Security (TLS v1) protocols. The mod_ssl package is available as a source extension and related patches for the Apache 1.3 Web server. - Install The mod_access Module
As its name implies, mod_access enables you to set special access controls on Web documents, as explained in the next section of these guidelines. - Install The mod_log_config Module
The mod_log_config module enables you to configure logging of Web accesses, as will also be explained shortly. - Run Only the Functions and Features That You Genuinely Need
Apache offers a number of functions and features that enhance its functionality, but that also introduce serious security liabilities. Avoid running these functions and features unless there is a bona fide need for them. Troublesome functions and features from a security standpoint include:- Server Side Includes (SSIs)
SSIs use the "exec cmd" element to start scripts and programs from SSI pages. The scripts and programs that are invoked run with the same privileges and permissions that Apache does, as set up in the httpd.conf file. This functionality is potentially very useful, but SSIs also introduce many liabilities, the worst of which is that it allows attackers the opportunity to enter input that may invoke rogue scripts and programs. Additionally, Apache must parse every SSI-enabled file, regardless of whether any SSI directives are included in the files. The downside is an increased load on the server, which in a shared server environment can significantly hurt performance.
Avoiding SSIs altogether is the safest alternative. You can completely disable the ability to run scripts and programs from SSI pages by replacing Includes with Includes NOEXEC in the Options directive. If disabling SSIs is not a viable option, you can substantially limit the use of SSIs by including >--#include virtual="..." --< to invoke CGI scripts only if these scripts are in directories listed in a ScriptAlias directive. Additionally, if you need SSIs, enabling suEXEC (which is included in Apache 1.2 and up) is a good security measure; this program allows scripts to run as a special, unprivileged user. suEXEC will be called using special hooks provided in the Apache code. For load-management purposes, files with .html or .htm extensions should not have SSIs enabled either. Assigning a separate extension (e.g., the .shtml extension) for all SSI-enabled files is a good idea; at a minimum, this enables you to readily identify all such files. - User Ability To Create Directories
Anyone who can create a directory can download hacking tools or Warez (copyrighted software); the "fun" begins from there. So avoid giving users the ability to create their own directories.
- Server Side Includes (SSIs)
4. Configuring Your Server Correctly
You'll need to do a number of things to ensure that your Apache server is configured in a manner that is conducive to security. This section describes the most important measures for configuring your server properly.
- Avoid Running Your Apache Server With Superuser Privileges
In its normal mode of operation, Apache starts as root, but then it changes to the user defined by the User directive to handle incoming connections. You have a choice concerning the level of privileges with which your Apache server will run, however. If you choose to run Apache with superuser privileges, there is a good chance that if an attacker exploits a bug in Apache, that person will gain superuser privileges. In UNIX and Linux systems, therefore, do not run your Apache server as root; avoid running it as SYSTEM or Administrator in Windows systems. Use the httpd.conf file to specify the level of privileges with which Apache will run. In Windows NT systems, avoid running your Apache server as Administrator or SYSTEM. - Keep Web-Related Directories And Files Away From System Directories And Files In The File System
It is important to ensure that your Web server resides in the proper location within your system’s directory structure. Keep all Apache-related directories and files as far away as possible from system directories and files.2 In Windows NT systems, always create at least two partitions, C: and D:. Dedicate C: to system files and D: to Apache-related directories and files. In the case of UNIX and Linux Web servers, do not include any Apache-related directories and files in /, /bin, /dev, /etc, /usr, /var, or any other system directory. Create a new directory under the root directory (or, in the case of Windows NT, under D:), and use this as the Web server’s root directory. - Compartmentalize The Web Directory Structure
Regardless of whether you are running UNIX, Linux, or Windows NT, create at least four subdirectories below the Web root directory, as follows:
Compartmentalizing the directory structure makes it much more difficult for an attacker who obtains access to one directory to do much to your Web server very quickly. Unless the attacker can determine what other directories exist and how to get to them, potential damage will be limited to the one directory. Restrict Directory Access As Needed
If you have included the mod_access module in your compiled version of Apache, you can use the mod_access directives to restrict access to certain directories. These directives are a significant advantage when it comes to access control. You can limit or allow access on the basis of hostname, and/or IP address, and/or the correct entry of a username and password. File system permissions do not allow this range of access control options. mod_access directives include:Directive
Definition
Allow
determines which hosts can access an area of the Web server
Deny
restricts access to the web server on the basis of hostname, address, and so on
Order
determines the default access state and order by which the Allow and Deny directives are evaluated
Require
determines the authenticated users who can access a directory
Satisfy
combination of Allow and Require (useful only if access to a particular area is limited by both a username-password combination and client address)
First and foremost, deny default access to directories by inserting the following in your server's configuration:<Directory /> Order Deny,Allow Deny from all </Directory>
Next, make exceptions by allowing access the directories intended for Web user access. For example, the following allow access to the /usr/users/*/public_html and /usr/local/httpd directories:<Directory /usr/users/*/public_html> Order Deny,Allow Allow from all </Directory> <Directory /usr/users/*/public_html> Order Deny,Allow Allow from all </Directory>
As an additional precaution, ensure that all directories that can be reached by unprivileged users have appropriate file system permissions. Unprivileged users should at a minimum (with the exception explained below) not be able to write to directories within the Web server. All Web-related files should be owned by you, the Webmaster.
Of all the directories Apache uses, ServerRoot (and the files it contains) is by far the most important. It is thus critical that ServerRoot in particular is protected against modification by unprivileged users. ServerRoot itself, its parent directories, its files, and its subdirectories should be writable only by root. If, for instance, you make /usr/local/apache the ServerRoot, you should chown ownership of this directory as well as its child directories to root (uid 0). Use the following commands:mkdir /usr/local/apache cd /usr/local/apache mkdir bin conf logs chown 0 . bin conf logs chgrp 0 . bin conf logs chmod 755 . bin conf logs
The parent directories, /, /usr, and /usr/local, should also be modifiable only by root. This will prevent an interruptable path problem.3 When you install the httpd executable, you should ensure that it is similarly protected:cp httpd /usr/local/apache/bin chown 0 /usr/local/apache/bin/httpd chgrp 0 /usr/local/apache/bin/httpd chmod 511 /usr/local/apache/bin/httpd
If users need to post files to a directory or modify files, create an htdocs subdirectory that is modifiable by whatever group of users needs to access it. Ensure that no file that root needs to execute, nor any root-created file, are in this subdirectory or in any subdirectory below it; otherwise, an attacker could replace one or more httpd binaries with malicious code, and then execute the code with root privileges.
Be especially careful of potential interactions between Location and Directory directives. <Directory /> may deny access, but a <Location /> directive might supersede the Directory directive. Additionally, it is best to avoid using the UserDir directive. Setting it to "./" or other, similar parameters for root can also supersede an appropriate Directory directive. In Apache 1.3 or higher, include the following entry in your Web server's configuration files to disable the UserDir directory:UserDir disabled root
Restrict Access To Files and Documents As Needed
mod_access directives can also limit access to individual files and documents. The following will, for example, limit access to the htpasswd users file:Deny from all Allow from domain.com AuthType Basic AuthUserFile /usr/local/apache/conf/htpasswd.users AuthName "special directory" Require valid-user Satisfy any
Additionally, in UNIX and Linux, ensure that whatever group Apache runs as is not given a write permission to any file. The default UNIX and Linux installation of Apache runs with the nobody uid and gid. This is not altogether bad, but because nobody is used in a number of nonrelated contexts (e.g., for anonymous NFS mounts), it is better to create a separate user and group used only for Apache access.- Restrict Access To Common Gateway Interface (CGI) Script Interpreters
You also need to restrict access to Common Gateway Interface (CGI) script interpreters. If users are given the ability to directly access CGI script interpreters, they can write malicious scripts and run them! Any user access to CGI script interpreters should be indirect, i.e., by processes that run scripts on behalf of users. In other words, users should not be given access to shell environments that allow them to enter commands that can be interpreted. Enable Logging and Inspect the Log File Regularly
Apache offers logging that is independent of operating-system logging. In most cases it is advisable to enable Apache logging, because it contains information, such as the commands entered as users have interacted with your Web server, that operating-system logging is likely to miss. First, include the mod_log_config module before compiling Apache. There are four logging-related directives:Directive
Description
TransferLog
for creating a log file
LogFormat
for specifying a custom format
CustomLog
for both creating and formatting a log file
CookieLog
for naming files that hold cookie logging
For additional information concerning these directives, visit .
The rotatelogs utility in the src/support/ directory supports rotation of the Apache log files. If you want rotation of log files every other day,4 include the following entry:TransferLog "|/path/to/rotatelogs /path/to/logs/access_log 172800"
Simply having logging enabled does little good, however. Given the volume of attacks against Web servers, inspecting Web logs daily or every other day has become a necessity.Disable Automatic Directory Listings
Directory listings can be useful when a browser requests a URL that includes a directory name, but the directory does not contain a filename that corresponds to the DirectoryIndex directive. If mod_autoindex is set to list directory contents, users can list these contents while attempting to find files. But this is not good for security — it can enable attackers to learn names of files within a directory, enabling them to attempt to obtain access, even if access to them is undesirable because, for example, the information in them is sensitive. It is best, therefore, to turn off automatic directory indexing. To do this, delete the Indexes keyword from the appropriate Options line. To turn off the ability to list a specific subdirectory, go to the Options directive and insert the entry "Options --Indexes," as has been done in the following example:<Directory_path> Options -Indexes </Directory>
Ensure That All Web Access Is Authenticated With Secure Authentication
First and foremost, make sure that all access to Web servers is authenticated. Failure to authenticate users is an open invitation to trouble. But there are good ways and bad ways to authenticate users. Using the /etc/passwd file or the shadow password file (e.g., /etc/shadow in Solaris systems) for Web authentication in UNIX and Linux systems is a bad way. The problem is that Web authentication is not quite like basic operating system authentication. Many UNIX and Linux operating systems provide some kind of basic control against brute force password-guessing attacks by limiting the number of bad login attempts within a time period or the login attempt rate. Furthermore, these operating systems usually notify users of failed logins through lastlogin messages or other mechanisms. In contrast, Web-based authentication does not include bad login protection measures. If you use a password file for Web authentication, attackers can enter password after password until they enter the right one. Once they enter the correct password, they can now potentially gain access to the system itself, not just the Web server. Additionally, clients cache passwords for Web access. To glean passwords from clients, attackers simply need to put up a bogus Web page, such that when the client hits this page, it will retrieve that password from its cache and then send the password on behalf of the user.
A viable alternative is to use some kind of Web-based authentication that does not involve access to the passwd and shadow passwd files in UNIX and Linux systems. One tempting solution is to simply use the basic user authentication mechanisms incorporated into the HTTP protocol. Using .htaccess files is a good example. In this case, each Web server will have a database containing usernames and passwords. The implications for security, however, are not very good. Even if passwords in these files are hashed, which is not always the case, Web browsers will by default send passwords in cleartext, an ideal scenario for someone who has a sniffer placed on the network between the browser and server.
A better Web-based authentication method is to have the browser request a connection to a desired URL. The server should create a unique session ID and then send it in the clear to the browser. This is acceptable, of course, only if the particular session ID is never used again. The browser then retrieves the user's password from the password file, appends the URL and the session ID, and finally hashes everything before it sends it to the Web server. The server also cryptographically hashes the user's password (the version stored in its database), adds on the URL requested and session ID, and then hashes everything. After the browser transmits its hash to the server, the server compares the browser's hash to the one it has computed. If the correct password has been entered, the two hashes will be identical.
Finally, note that if you are not careful, users may be able to create and use custom .htaccess files, enabling them to authenticate through methods other than the ones you have set up. To keep .htaccess files other than those in directories that you specifically enabled for the purpose of authentication from being used, include the following entries in the server configuration file:<Directory /> AllowOverride None </Directory>
5. Writing Common Gateway Interface (CGI) Scripts Properly
CGI scripts provide a way to interact with Web servers. They extend a Web server's abilities by running programs that collect user input and then return results to users. Information can be passed to CGI scripts as standard input, or they can obtain information through environment variables (such as the browser being used) that are extracted from browser requests. They can also create pages "on the fly," based on data obtained during their execution. Although extremely functional, CGI is, unfortunately, a very basic process for handling interactions. It thus potentially creates a large number of vulnerabilities on the server in which it is used. These include:
CGI has few innate data/input checking mechanisms; by default, results of CGI execution are in fact almost invariably not filtered before being sent to the user. When CGI scripts are used to process Web page forms whenever users need to input data that you need to collect, weaknesses in the way these scripts are written can lead to CGI scripts running rogue commands on your system with the permissions and privileges of the Web server itself, unauthorized access to files, damage to your Web server (including defacement of Web pages and deletion or unauthorized modification of critical files), leakage of information about the system or its data, and a variety of other highly undesirable outcomes. For example, suppose there is a field in a Web form in which each user needs to enter a phone number. An attacker can enter:
512-690-3346;`rm -rf \*`
The attacker has appended additional characters to the phone number; if they are not filtered out, they may be executed, resulting in deletion of all Web server files.- Environment variables can cause similar problems. A clever attacker can craft environment variables that cause trouble for the Web server, such as execution of rogue commands.
- As mentioned previously, because many CGI programs use underlying command interpreters (e.g., Perl or UNIX), an attacker may be able to run programs that the designers of the system have not intended to run.
- Using calls such as system() or popen() that invoke shells (and also accept special shell characters). As mentioned previously, shell access to unprivileged Web users spells catastrophe; every attacker dreams of being able to reach a Web server with shell access!
- Bugs in many sample CGI scripts provided with the Apache server are well-known, thus providing a prime opportunity to attackers. A well-known vulnerability in PHF (a sample CGI script intended to show how a Web-based phone book can be set up), for example, allows an attacker to execute any command on a Web server with the permissions of the process running the Web server.
- Solutions that counter these and other vulnerabilities include:
Write CGI scripts such that they test for allowable characters before your Web server uses any environment variable(s).
For example, if users are to enter a phone number in a Web page, the following string in the CGI script that receives this input will weed out illegal characters:$number=~/^[\d-]+{1,12}$/ || die "Non-allowed characters in input [0] ";
The start of this string basically means that phone numbers that are entered must conform to the specified rules. \d means to accept numerals; the "-" designates that hyphens in the phone number will also be accepted. The ^[\d-]+ means to allow any set of permitted characters (in this case, numerals), starting at the beginning of the line. The {1,12} means that to be accepted, the input must be between 1 and 12 characters in length. This length restriction is extremely important; it prevents buffer overflows 5 caused by excessively long input (e.g., 77777777777777777777777777777777777777777777777777777777`rm -rf *`). The $ means that when the string comparison is finished, you are now at the end of the line. These restrictions help preclude the possibility of an attacker inserting commands or metacharacters at the end of the input.
- Filter Environment Variables.
For reasons discussed previously, filter environment variables similarly to the way user input is filtered.
Drastically restrict user access to command interpreters. The rationale for this measure was also mentioned earlier.
Avoid calls such as system() or popen(); instead use fork() and then execve() to avoid calling a shell. This not only ensures that special shell characters will not be processed, but also precludes an extremely large number of well-known Web server attacks. To communicate with a spawned process, simply manually open a pipe through which input can be passed. Delete All Sample CGIs
Well-known bugs in them can result in a variety of catastrophic outcomes. For example, a widely-known bug in PHF (a sample CGI script designed to show how a Web-based phone book can be implemented) can enable an attacker to run virtually any command on your Apache server with the privileges and permissions of the server itself. In addition to PHF, CGI scripts that you should delete include:aglimpse
campas
count.cgi
faxsurvey
handler
htmlscript
man.sh
nph-test-cgi
perl.exe
pfdisplay
php.cgi
service.pwd
test-cgi
users.pwd
view-source
webdist.cgi
webgais
websendmail
wwwboard.pl
www-sql
- Prevent the ability of unprivileged users to execute CGI scripts in any directory
The problem is that if unprivileged users can execute CGI scripts in any directory, they may write and then execute scripts that will purposely or accidentally compromise your Web server (or possibly the system on which the Web server runs). Limiting CGI scripts to certain directories not only allows the Webmaster control over the content of these directories, but also alleviates the need to inspect every directory to determine whether there is anything dangerous there.
Avoid SUID root scripts to the maximum possible extent. In Unix and Linux platforms, limiting SUID root scripts as much as possible lessens the probability that an unauthorized Web user will be able to gain root privileges.
- Solutions that counter these and other vulnerabilities include:
6. Ensuring That Vulnerabilities Are Patched
Although not as bad as the IIS Web server in terms of the sheer number of vulnerabilities, Apache nevertheless has had several vulnerabilities that need to be fixed if it is to run securely.
A vulnerability in the processing of certain types of chunk-encoded HTTP requests in Apache versions 1.3 through 1.3.24, as well as in versions 2.0 through 2.0.36, may enable remote attackers to run rogue code. The potential result is damage to your Web server and compromise of data not intended for access by Web users. The easiest solution is to upgrade to Apache 2.0.40. Another alternative is to add the following directive to the global server configuration prior to the first Alias or 'Redirect' directive in the httpd.conf file:
RedirectMatch 400 "\\\.\."
Still another solution is to download a fix for this vulnerability. Visit .
- Multiple vulnerabilities in the PHP scripting language versions 4.2.0 or 4.2.1 can allow a remote attacker to run rogue code or to crash PHP and possibly your Web server itself. The problem is in the part of PHP code ("multipart/form-data") that handles file uploads. An attacker can send a specially formed POST request to the Web server that results in an improperly initialized memory structure being freed. For more detail (including information about patches available from vendors) go to .
- Another problem ("cross-site scripting vulnerabilities") related to complex interactions between components used for Web access can allow an unauthorized remote person to take control of interactions between a user and a Web site. The problem is related to improper encoding of data to be viewed by the user. Apache-SLL is also vulnerable to this problem. Although Apache 1.3.12 provides some protection against some instances of this problem, fixing this problem requires a number of additional actions. Visit
.
A buffer overflow condition exists in mod_ssl within Apache-SSL. Downloading Apache-SSL 1.3.26+1.47 fixes this problem.6 Go to . - Multiple vulnerabilities in Apache-OpenSSL can result in unauthorized root privileges, or denial of service. Fixes include upgrading to version 0.9.6e of OpenSSL, installing the combined patches for OpenSSL 0.9.6d, which are available at
; or, if your system runs OpenSSL pre-release version 0.9.7-beta2, upgrading to 0.9.7-beta3, which fixes the previously mentioned vulnerabilities.
Alternatively, combined patches for OpenSSL 0.9.7-beta2 are available at .
Please note that after applying the patches or upgrading the OpenSSL version, you will need to recompile all applications that use OpenSSL to support SSL/TLS, and then restart these services. - A vulnerability in Apache 2.0.39 can allow an attacker to discover the path to files and directories within the Web server. Upgrading to 2.0.40 solves this problem. A workaround can also be applied. See
.
Running as recent a version of Apache as possible is a good idea in that you are likely to have to install fewer fixes. Version 2.0.40, for example, corrects a number of vulnerabilities. Version 1.3.27 also fixes a number of vulnerabilities in the Apache version 1 series. You can visit for all Apache patches.
Additional Security Measures
- Helping to protect sensitive information in HTML forms by setting variables to the "hidden" attribute. This information will not be displayed when users access it via a Web browser. However, it is important to realize that someone can nevertheless view this information by saving the form as a text file. Someone could also modify the values of hidden variables while the form is a text file and then use a browser to bring the form up again and submit it. Still, it is better for the sake of security to set variables to the "hidden" attribute than to not do so — some security is better than none.
- Hiding the Apache version number and the name of the OS that is running to keep attackers from discovering them, then tailoring attacks accordingly. The ServerTokens directive in the configuration file controls whether or not the version number and OS version are sent back to clients.
- Running security tools. Given the dangers of Web servers in general, using additional security tools is highly advisable. Unfortunately, there are too many to discuss here. As an example of how handy these tools can be, consider two of them, chkrootkit and logcheck for Solaris. chkrootkit (available as chkrootkit-0.35-sol8-sparc-local.gz) locally detects whether a rootkit 7 has been installed. chkrootkit, which requires root privileges to run, must be installed in /usr/local/chkrootkit. To start it, you must cd to /usr/local/chkrootkit, then enter ./chkrootkit or sh ./chkrootkit. logcheck (available as logcheck-1.1.1-sol8-sparc-local.gz) inspects Solaris log files to detect attacks and anomalous activity. This tool must be installed in /usr/local. Visit to obtain both tools.
References
Footnotes
- Apache is also available in Mac OS X, which is not specifically covered in this document because this OS is FreeBSD Unix. Note that Windows NT and many flavors of Linux and Unix are not very secure immediately after installation. If you want them to be secure, you’ll need to invest some effort in changing configuration settings, disabling default accounts, and so forth.
- This lessens the probability that a Web user can obtain access to system files.
- The interuptable path problem in Unix and Linux occurs whenever world or some other unprivileged uid has write permissions to a directory. This allows anyone who can write to the directory to use the mv command to take ownership of all files and directories below this directory. Additionally, if any directory such as the logs directory is writable by any unprivileged user, an attacker can replace any data file such as a log file with a symbolic link to another system file, resulting in that file being overwritten with arbitrary or empty data.
- A more sophisticated logfile rotation utility, cronolog, is available at .
- See for additional information concerning how to prevent buffer overflows.
- Do not use version 1.46, however, as it is vulnerable.
- A rootkit is a tool that masquerades the presence of an attacker in a compromised system.