Description
These steps below will help you secure your Apache httpd webserver and VirtualHosts against various types of threats or attacks.
Purpose & Scope
The purpose of this document is to help you identify problem areas or areas of concern that deserve proper attention and consideration in your policy.
Most of the directives below are part of the Apache httpd mod_headers module.
1 2 3 | <ifModule mod_headers.c> Header set header_name "header_value" </ifModule> |
- Avoid Access-Control-Allow-Origin: *
- Establish a Cross-Domain Meta Policy
- Prohibit MIME Sniffing
- Remove Server Identifier
- Remove X-Powered-By
- Enable Strict MSIE XSS Protection
- Prohibit Content Framing
- Content Security Policy
- JavaScript
- CSS
- HTML frames
- web workers
- fonts
- images
- Java applets
- ActiveX
- audio and video files
- other HTML5 features
- Implement SSL/TLS
- Strict Transport Security (HSTS)
- Disable access to wp-config.php
- Disable access to xmlrpc.php
- Disable access to .htaccess
It is not uncommon for a modern website to include content delivered from another domain. For example, your website might include your recent Facebook posts, or what you recently posted on Twitter. Facebook and Twitter serve this content through their public APIs. A specification called Cross Origin Resource Sharing (CORS) is often used as part of the process.
You also might provide an API to content or resources on your server. Your API might allow for POST, PUT or DELETE requests. These methods are able to add, change or delete content on your database or web-server.
Do not use wide open configurations like this:
1 2 3 4 5 6 | ############## # DO NOT USE # ############## <ifModule mod_headers.c> Access-Control-Allow-Origin: * </ifModule> |
Instead use something more specific like this:
1 2 3 4 5 6 | ############### # INSTEAD USE # ############### <ifModule mod_headers.c> Access-Control-Allow-Origin: https://verified-site.com/ </ifModule> |
Disallow others from using your content in their sites.
1 2 3 | <ifModule mod_headers.c> Header set X-Permitted-Cross-Domain-Policies "none" </ifModule> |
MIME-sniffing provides an attack vector that malicious people can use to have the web-browser execute embedded scripts in specially crafted resources. Disable this to prevent these attacks.
1 2 3 | <ifModule mod_headers.c> Header set X-Content-Type-Options "nosniff" </ifModule> |
In the HTTP headers that your web-server returns with each web-page (or asset) there is probably a string that looks similar to this:
Server: Apache/2.2.17 (Fedora)
That innocent looking string tells the hacker what web-server software they’re dealing with (Apache), what the version of that software is (2.2.17) and even what operating system is running on the web-server (Fedora). The problem here is that you’re giving away too much information.
It’s much better to not reveal this information if we can help it.
Method #1
ServerTokens and ServerSignature Directives – This method should be added top your main configuration file /etc/httpd/conf/httpd.conf
or at the top of the VirtualHost file /etc/httpd/conf.d/vhosts.conf
1 2 | ServerSignature Off ServerTokens Prod |
note: The most restrictive setting here still sends the webserver software but does not send operating system or software versions.
ServerTokens Prod
Server sends (e.g.): Server: Apache
Method #2
mod_security – This method will completely remove all information.
This method requires the use of mod_security and is no light subject, if you plan to implement this, read the docs on mod_security before continuing with this step, mod_secuity can break your website if not configured properly
1 2 3 | <ifModule ModSecurity.c> SecServerSignature '' </ifModule> |
Like the Server Identifier, PHP will also send its version in the response header, again, giving away too much information about the server.
X-Powered-By: PHP/5.5.30
1 2 3 | <ifModule mod_headers.c> Header unset X-Powered-By </ifModule> |
Microsoft’s Internet Explorer (MSIE) software has integrated protection against XSS attacks. You can instruct MSIE browsers in how to behave when they encounter a suspected XSS attack. The most secure protection is to totally block a suspect website.
1 2 3 | <ifModule mod_headers.c> Header set X-XSS-Protection "1; mode=block" </ifModule> |
Clickjacking is an attack where the hacker instructs the web-browser to render your website content beneath an invisible layer that has malicious click destinations overlaid atop your links.
1 2 3 | <ifModule mod_headers.c> Header set X-Frame-Options "DENY" </ifModule> |
A Content Security Policy (CSP) is a set of directives in your webserver configuration that govern content. They dictate what type of content you may use on your website and from which sources it may originate. The fine-grained control offered by a good CSP rule-set is probably the best defense against XSS and data injection attacks that you can achieve. These attacks are used for everything from data theft to site defacement or distribution of malware. Furthermore, all modern browsers are able to parse and act on a CSP.
Content Security Policy (CSP) is complex and can take time to understand, configure and test. You should read the Mozilla Developer Network documents on CSP before implementing any rulesets.
Covered types are:
Embeddable objects such as:
Highly restrictive ruleset:
1 2 3 4 5 6 | ######################################################################### # DO NOT USE, EXAMPLE ONLY TOO RESTRICTIVE, WILL LIKELY BREAK YOUR SITE # ######################################################################### <ifModule mod_headers.c> Header set X-Content-Security-Policy "default-src 'self'; img-src 'self'; style-src 'self' 'unsafe-inline'; font-src 'self'; script-src 'self' 'unsafe-inline'; connect-src 'self';" </ifModule> |
See this document on setting up SSL / TLS.
To avoid MITM (man-in-the-middle) attacks where a user hijacks the communication stream during the process, which is possible for a split second during a redirect from http -> https, enable HSTS (this setting will cause problems with non-ssl subdomains, remove includeSubdomains;
) below:
1 2 3 | <ifModule mod_headers.c> Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload" </ifModule> |
1 2 3 4 5 6 7 8 9 10 11 12 | ## Apache httpd 2.2 ## ## Disable access to wp-config.php ## <Files wp-config.php> Order allow,deny Deny from all </Files> ## Apache httpd 2.4 ## ## Disable access to wp-config.php ## <Files wp-config.php> Require all denied </Files> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | ## Apache httpd 2.2 ## ## Disable access to xmlrpc.php ## <Directory /var/www/example.com/> <Files xmlrpc.php> Order allow,deny Deny from all </Files> ## Apache httpd 2.4 ## ## Disable access to xmlrpc.php ## <Directory /var/www/example.com/> <Files xmlrpc.php> Require all denied </Files> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | ## Apache httpd 2.2 ## ## Prevent .htaccess files from being spidered or viewed via a web browser ## <FilesMatch "^\.ht"> Order allow,deny Deny from all satisfy all </FilesMatch> </Directory> ## Apache httpd 2.4 ## ## Prevent .htaccess files from being spidered or viewed via a web browser ## <Files ".ht*"> Require all denied </Files> </Directory> |