When it comes to website security, most people are quite oblivious to the vulnerabilities that exist and are exposed on their own site.
Securing your website is all about minimizing attack surface and adding more layers of security. One strong layer that you can (and should) add is proper HTTP security headers. When responding to requests, your web server should include a number of security headers that help stop unwanted activity like XSS, MITM, and click-jacking attacks. While sending security headers does not guarantee 100% defense against all such attacks, it does help modern browsers keep things secure. So in this tutorial, we walk through seven of the most important and effective HTTP security headers you should add to your website in order to your website to bolster the security.
Note that the solutions below only work on Apache and compatible servers that use .htaccess, such as Litespeed.
Here are 7 Important HTTP Security Headers for Your Website.
- HTTP Strict Transport Security (HSTS)
- All Together
Note: You can verify your site’s security headers using a free online tool such as the one provided by SecurityHeaders.com.
X-XSS-Protection security header enables the XSS filter provided by modern web browsers (IE8+, Chrome, Firefox, Safari, et al). Here is the recommended configuration for this header:
# X-XSS-Protection <IfModule mod_headers.c> Header set X-XSS-Protection "1; mode=block" </IfModule>
Added to your site’s
.htaccess file or server configuration file, this code instructs supportive browsers to block any requests containing malicious scripts. For more configuration options and further information about
X-XSS-Protection, check out these resources:
- MDN Docs: X-XSS-Protection
- X-XSS-Protection – Preventing Cross-Site Scripting Attacks
- Increase Security with X-Security Headers
X-Frame-Options (XFO) security header helps modern web browsers protect your visitors against clickjacking and other threats. Here is the recommended configuration for this header:
# X-Frame-Options <IfModule mod_headers.c> Header set X-Frame-Options "SAMEORIGIN" </IfModule>
Added to your site’s
.htaccess file or server configuration file, this code instructs supportive browsers to block any frames/content requested from external locations. So if your own site includes an iframe that loads a resources from the same domain, the content will load normally. But if any iframe is included that loads resources from any other domain, the content will be blocked. For more configuration options and further information about
X-Frame-Options, check out these resources:
X-Content-Type-Options security header enables supportive browsers to protect against MIME-type sniffing exploits. It does this by disabling the browser’s MIME sniffing feature, and forcing it to recognize the MIME type sent by the server. This header is very flexible and may be configured extensively, however the most common implementation looks like this:
# X-Content-Type-Options <IfModule mod_headers.c> Header set X-Content-Type-Options "nosniff" </IfModule>
Added to your site’s
.htaccess file or server configuration file, this code instructs supportive browsers to use the MIME type declared by the origin server. There are a couple of precautions to keep in mind. First, as with any security header, it does not stop 100% of all attacks or threats; it does stop some of them, however, and thus provides another layer of protection for your site. Also note that this header currently is supported only in Chrome and later versions of Internet Explorer. Hopefully other browsers will add support in the future. For more configuration options and further information about
X-Content-Type-Options, check out these resources:
Strict-Transport-Security (HSTS) header instructs modern browsers to always connect via HTTPS (secure connection via SSL/TLS), and never connect via insecure HTTP (non-SSL) protocol. While there are variations to how this header is configured, the most common implementation looks like this:
# Strict-Transport-Security <IfModule mod_headers.c> Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains" </IfModule>
Added to your site’s
.htaccess file or server configuration file, this code instructs supportive browsers to always use HTTPS for connections. This helps stop man-in-the-middle (MITM) and other attacks targeting insecure HTTP connections. For more configuration options and further information about
Strict-Transport-Security, check out these resources:
Referrer-Policy security header instructs modern browsers how to handle or exclude the
Referer header (yes the header normally is spelled incorrectly, missing an “r”). For those who may not be familiar, the
Referer header contains information about where a request is coming from. So for example if you are at
example.com and click a link from there to
Referer header would specify
example.com as the “referring” URL.
With that in mind, the
Referrer-Policy enables you to control whether or not the
Referer header is included with the request. Here is an example showing how to add the
Referrer-Policy header via Apache:
# Referrer-Policy <IfModule mod_headers.c> Header set Referrer-Policy "same-origin" </IfModule>
Added to your site’s
.htaccess file or server configuration file, this code instructs supportive browsers to only set the referrer header for request from the current domain (
same-origin). Keep in mind that this header is less about security and more about controlling referrer information, as is required by various rules and regulations (e.g., GDPR). For more configuration options and further information about
Referrer-Policy, check out these resources:
Feature-Policy header tells modern browsers which browser features are allowed. For example, if you want to ensure that only geolocation and vibrate features are allowed, you can configure the
Feature-Policy header accordingly. It also enables you to control the origin for each specified feature. Here is an example showing how to add a
Feature-Policy header via Apache:
# Feature-Policy <IfModule mod_headers.c> Header set Feature-Policy "geolocation 'self'; vibrate 'none'" </IfModule>
Added to your site’s
.htaccess file or server configuration file, this code instructs supportive browsers to enable only geo-location and vibrate features. Keep in mind that this header is less about security and more about ensuring a smooth experience for your users. For more configuration options and further information about
Feature-Policy, check out these resources:
Content-Security-Policy (CSP) header tells modern browsers which dynamic resources are allowed to load. This header is especially helpful at stopping XSS attacks and other malicious activity. This header provides extensive configuration options, which will need to be fine-tuned to match the specific resources required by your site. Otherwise if the header configuration does not match your site’s requirements, some resources may not load (or work) properly.
Because of this, there isn’t one most common example to look at. So instead here are a few different examples, each allowing different types of resources.
First example, here is a CSP directive that allows resources from a CDN, and disallows any framed content or media plugins. This example is from the Google docs page linked below.
# Content-Security-Policy - Example 1 <IfModule mod_headers.c> Header set Content-Security-Policy "default-src https://cdn.example.com; child-src 'none'; object-src 'none'" </IfModule>
Second example, this CSP directive enables script resources loaded from a jQuery subdomain, and limits stylesheets and images to the current domain (
self). This example is from the Mozilla docs page linked below.
# Content-Security-Policy - Example 2 <IfModule mod_headers.c> Header set Content-Security-Policy "default-src 'none'; img-src 'self'; script-src 'self' https://code.jquery.com; style-src 'self'" </IfModule>
And for a third example, here is the directive I use on most of my WordPress-powered sites. Logically these sites tend to use the same types of resources, so I can keep things simple and use the following code on all sites:
# Content-Security-Policy - Example 3 <IfModule mod_headers.c> Header set Content-Security-Policy "default-src https:; font-src https: data:; img-src https: data:; script-src https:; style-src https:;" </IfModule>
To get a better idea of what’s happening here, let’s apply a bit of formatting to the code:
Header set Content-Security-Policy " default-src https:; font-src https: data:; img-src https: data:; script-src https:; style-src https:; "
Stare at that for a few moments and you should get the idea: the header is setting the allowed source(s) for fonts, images, scripts, and styles. For each of these, a secure HTTPS connection is required. The only exception is also to allow
data URIs as a source for fonts and images.
So for any of these examples, when added to your site’s
.htaccess file or server configuration file, the code tells supportive browsers which dynamic resources are allowed and/or not allowed. But seriously, if you’re thinking about adding the powerful
Content-Security-Policy security header, take a few moments to read thru some of the documentation:
- MDN Docs: Content Security Policy
- MDN Docs: Implementing Content Security Policy
- Google Docs: Content Security Policy
- Content Security Policy Reference
Where to get help with CSP
Yes CSP can be confusing, but there is no reason to despair. There are numerous online tools that make it easier to figure out how to implement CSP, for example here are some top sites:
A quick search for “csp test online” yields many results.
Even better, they now have “CSP generators” that literally write the code for you based on your input variables. Here are two solid looking CSP generators:
There are lots of useful tools out there to make CSP easier. Just enter your infos and copy/paste the results. If in doubt, use multiple tools and compare the results; the code should be the same. If not, don’t hesitate to reach out to the tool providers, who will be able to answer any questions, etc.
For the sake of easy copy/pasting, here is a code snippet that combines all of the above-described security headers.
Important: before adding this code to your site, make sure to read through each technique as explained in corresponding sections above. There may be important notes and information that you need to understand regarding each particular directive included in this code snippet.
# Security Headers <IfModule mod_headers.c> Header set X-XSS-Protection "1; mode=block" Header set X-Frame-Options "SAMEORIGIN" Header set X-Content-Type-Options "nosniff" Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains" # Header set Content-Security-Policy ... Header set Referrer-Policy "same-origin" Header set Feature-Policy "geolocation 'self'; vibrate 'none'" </IfModule>
As with each of the above techniques, this code may be added to your site via .htaccess or Apache config. Understand that this technique includes commonly used configurations for each of the included headers. You can (and should) go through each one to make sure that the configuration matches the requirements and goals of your site. Also remember to test thoroughly before going live.
Note: Notice the following line in the above “Security Headers” code snippet:
# Header set Content-Security-Policy ...
The pound sign or hash tag or whatever you want to call it means that the line is disabled and is ignored by the server. This means that the
Content-Security-Policy directive is “commented out” and thus not active in this technique. Why? Because as explained previously, there is no recommended “one-size-fits-all” CSP example that works perfectly in all websites. Instead, you will need to replace the commented out line with your own properly configured CSP header, as explained above.
Once you are done, you can use these handy Geekflare Tools to test that your security headers are working properly.