Websites are constantly under attack, and many of them become exploited through vulnerabilities, usually due to outdated software. The safety of a website can greatly benefit from security headers. There are many types of attacks and security headers, so for the time being we will try to only mention the most important ones.

How do security headers protect my website?

You can add an extra layer of security by using HTTP security headers, which can block common malicious activity from negatively affecting your website's performance, stability, and security. Modern browsers support a large set of HTTP headers that can protect against clickjacking, cross-site scripting, and other common attacks.

What Are Security Headers?

The HTTP headers are used to pass additional information between the clients and the server through the request and response header. The security headers are passed through the HTTP header response as rules which browsers have to follow. A header response can inform your browser of a "Page Not Found" for example. As to security headers, those are the directives which protect your website in some way, for example by allowing the browser to only load certain types of files from your own domain and reject downloads from third parties. A security directive like that will block a browser from downloading malicious files from another website. The restrictions imposed by the security headers allow you to prevent malicious activities, such as XSS, code injection, clickjacking, etc.

Let’s have a look at some of the most important security headers that will give your site some much-needed protection. Please bear in mind that all our servers run Apache as web server, so all examples are for this type of web environment.

X-Frame-Options

The so-called Clickjacking spoofing technique was very popular back in the day and still is. Attackers still try to trick users into clicking on malicious links by making emails or websites appear as official and legitimate. X-Frame-Options help guard against such attacks by simply limiting or fully disabling iframes present on the site, so your pages cannot be embedded on third-party websites. Here are several examples.

Fully disable the use of iframes:

Header always set X-Frame-Options "deny"

The page can only be embedded in a frame on a page with the same origin as itself, which means you can only embed pages within your own website:

Header always set X-Frame-Options "sameorigin"

The embedded page can be displayed in a frame on the specified origin, meaning that your content can be embedded only on a website which you have specified as trusted. This only works in browsers that support this security header and does not work with multiple domains:

Header always set X-Frame-Options "allow-from https://www.trusted-site.com/"

The added security is provided only if the user accessing the document is using a browser that supports X-Frame-Options. The Content-Security-Policy HTTP header has a frame-ancestors directive which obsoletes this security header for supporting browsers.

Content-Security-Policy (CSP)

A very basic example of a Content-Security-Policy

The HTTP Content-Security-Policy response header allows website administrators to control resources the browser is allowed to load for a given page. In other words, you can whitelist your site’s content sources. Content Security Policy evaluates and blocks requests for assets.

Cross-site scripting (XSS)

The CSP mainly detects and mitigates XSS attacks. The user's browser can be exploited by having it load seemingly trusted and secure content, when the loaded assets could in fact expose the victim's browser to the execution of malicious scripts downloaded from an unknown source. The website administrator has the ability to impose restrictions and specify which Internet domains should be considered as safe sources of executables.

Packet sniffing and forced HTTPS

In addition to specifying the trusted sources of content loaded on your pages, you can also specify the allowed protocols, e.g. "always use HTTPS". However, a good data transfer protection policy consists of not only the implementation of HTTPS but also marking all cookies with the secure attribute as well as redirecting all HTTP requests to HTTPS. Additionally, sites may use HTTP Strict-Transport-Security (HSTS) to ensure that the connection between the browsers and the website is always encrypted.

Let's take a look at the list of CSP properties you can use to protect your pages.

Main CSP security header properties

  • default-src
  • script-src
  • img-src
  • media-src
  • object-src
  • manifest-src
  • frame-ancestors
  • form-action
  • plugin-types
  • base-uri

For a complete and up-to-date list of properties, refer to Mozilla.

One of the most commonly used request headers is "upgrade-insecure-requests". To utilize it, you just need to add the following line to the .htaccess file present in the document root of your website:

Header always set Content-Security-Policy: upgrade-insecure-requests

In a nutshell, this converts all HTTP requests to HTTPS.

Here is another example in which your pages are generally restricted to loading assets from your own domain, but embedded elements from Stripe and YouTube can be loaded on your pages:

Header always set Content-Security-Policy "default-src 'self'; frame-ancestors 'self' *.trusted-domain.com; frame-src 'self' https://js.stripe.com https://www.youtube.com"

frame-src allows you to specify the locations from which content can be embedded to your pages. This differs from frame-ancestors, which enables you to specify the locations that are allowed to embed content from your website.

For any policy, it is recommended that you first run it in report-only mode, so that you first review your setup. It is also recommended that you always use report-uri (deprecated but still used) and report-to (successor of report-uri) when deploying a policy to understand what is being blocked:


Header always set Reporting-Endpoints default="https://my-domain.com/reports"

Header always set Content-Security-Policy-Report-Only "default-src 'self'; frame-ancestors 'self' *.trusted-domain.com; frame-src 'self' https://js.stripe.com https://www.youtube.com; report-uri /some-report-uri; report-to default"

For the reporting to work, you need to configure an endpoint to which the reports will be sent. You can check the Mozilla documentation on Content-Security-Policy for more information on setting up the script running at the endpoint address, which will actually log the JSON detailing the violation(s).

Setting up a Basic CSP

The following configuration assumes that:

  • All resources are hosted by the same domain of the document.
  • There are no inlines or evals for scripts and style resources.
  • There is no need for other websites to frame the website.
  • There are no form-submissions to external websites.
Header always set Content-Security-Policy "default-src 'self'; frame-ancestors 'self'; form-action 'self';"

This policy should be carefully considered allowing the content that you intend to load but block everything else.

X-Content-Type-Options

Blocks a request if the request destination is of type style and the MIME type is not text/css, or of type script and the MIME type is not a JavaScript MIME type. In a nutshell, the following tells the web browser that the Content-Type security headers are deliberately set and should be followed:

Header always set X-Content-Type-Options "nosniff"

Secure Cookies

To protect your cookies by only sending them via HTTPS (HTTP over SSL/TLS) and effectively stop attackers from having any chance of eavesdropping on the communication channel between the browser and the server, just add the following to your .htaccess file:

Header always edit Set-Cookie (.*) "$1;HttpOnly;Secure"
RewriteEngine On
RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)
RewriteRule .* - [F]

Referrer-Policy

Using this HTTP response security header, you can limit the amount of information that may be shared with third parties.

  • no-referrer: No referrer information is sent. Keep in mind that this will block referrer information in your own logs. If you need this information for analytics purposes, you may want to choose other options.
  • no-referrer-when-downgrade: Sends full referrer information unless the security protocol is being downgraded from https to http. This is the default setting for older browsers.
  • origin: Only sends the origin (https://example.com) as the referrer and strips out the path and query string.
  • origin-when-cross-origin: Same as "origin" except when the origin matches the request, full referrer information is sent.
  • same-origin: Same as "no-referrer", except when the origin matches the request, full referrer information is sent.
  • strict-origin: Same as "origin" except if the security protocol is different, don't send anything.
  • strict-origin-when-cross-origin: Sends full referrer information if the origin matches the request. If not, send only the origin unless the security protocol is being downgraded, in which case send nothing. This is the default setting for modern browsers.
  • unsafe-url: Sends full referrer information on all requests (not recommended).

To always set the default setting for modern browsers, add the following to your .htaccess file:

Header always set Referrer-Policy: "strict-origin-when-cross-origin"

Conclusion

In modern days, with all the automatic bots crawling your pages in search of vulnerabilities, it is definitely worth it to add security headers as one more layer of protection. The security headers, however, should be added on top of up-to-date software and hardened server environment. Always keep in mind that some security headers require a customized configuration, so you should carefully examine the assets which your website loads to avoid content-related issues. We recommend that you regularly run updates on your applications and revise your custom scripts, so they can remain secure and free of security holes, because keeping the Internet users safe should be of utmost importance for any website.

Author

A web hosting provider since 2001. We host over 58,000 websites for customers in over 140 countries around the globe.