Following the recent declaration of my new service, https://securityheaders.io, I thought I'd cover some more than of the security based HTTP response headers out there and look at how to harden your existing HTTP response headers.


Introduction

HTTP Response headers are name-value pairs of strings sent back from a server with the content you requested. They are typically used to transfer technical information like how a browser should cache content, what type of content it is, the software running on the server and much, much more than. Increasingly, HTTP Response headers have been used to transmit security policies to the browser. By passing security policies back to the customer in this fashion, hosts can ensure a much safer browsing experience for their visitors and also reduce the chance for everyone involved. Let'south take a look at some more than security based headers.


Additional Headers

The first step in hardening your HTTP response headers is looking at the additional headers you can use to make your site more secure. Outlined below, these headers requite the browser more than information about how you want it to behave with regards to your site. They can exist used to deliver security policies, set configuration options and disable features of the browser you don't want enabled for your site. Once you lot have setup each header, check it using SecurityHeaders.io.


Content Security Policy

The CSP header allows you to define a whitelist of canonical sources of content for your site. By restricting the assets that a browser tin can load for your site, like js and css, CSP can human activity as an constructive countermeasure to XSS attacks. I accept covered CSP in a lot more detail in my blog Content Security Policy - An Introduction. Hither is a basic policy to enforce TLS on all assets and forestall mixed content warnings.

NginX:

          add_header Content-Security-Policy "default-src https: data: 'unsafe-inline' 'unsafe-eval'" ever;                  

Apache:

          Header always set Content-Security-Policy "default-src https: data: 'unsafe-inline' 'unsafe-eval'"                  

For Windows Servers open up upward the IIS Manager, select the site you want to add the header to and select 'HTTP Response Headers'.

IIS Response Headers

Click the add together button in the 'Actions' pane and then input the details for the header.

IIS CSP Header

CSP has a huge number of features that I've outlined in the blog mentioned to a higher place and y'all tin as well use my CSP Analyser and CSP Architect over on study-uri.io to help you create a tailored policy for your site.


HTTP Strict Transport Security

Sites have always heavily relied on a 301/302 redirect to accept users from browsing over HTTP to HTTPS. With browsers defaulting to HTTP when y'all type in an address like scotthelme.co.u.k., this has previously been the simply way. HSTS allows you to tell a browser that you always want a user to connect using HTTPS instead of HTTP. This means whatsoever bookmarks, links or addresses the user types will be forced to employ HTTPS, fifty-fifty if they specify HTTP. Read more in my blog on HSTS - The Missing Link In Transport Layer Security and check out HSTS Preloading too. This policy will enforce TLS on your site and all subdomains for a year.

NginX:

          add_header Strict-Send-Security "max-age=31536000; includeSubdomains" e'er;                  

Apache:

          Header always set Strict-Send-Security "max-historic period=31536000; includeSubDomains"                  

IIS:

IIS HSTS Header


HTTP Public Primal Pinning

The great thing nearly SSL/TLS certificates is that yous tin can buy a certificate from whatever trusted Certificate Authority and the browser will happily accept it. The trouble with this is that when a Certificate Dominance is compromised, an attacker tin can issue themselves an SSL/TLS certificate for your site and the browser will take this rogue document as it came from a trusted Certificate Authority. HPKP allows y'all to protect yourself past providing a whitelist of cryptographic identities that the browser should trust. Whilst HSTS says the browser must always employ HTTPS, HPKP says the browser should only ever accept a specific set of certificates. Read more than on my blog about HTTP Public Cardinal Pinning.

NginX:

          add_header Public-Key-Pins "pin-sha256='X3pGTSOuJeEVw989IJ/cEtXUEmy52zs1TZQrU06KUKg='; pin-sha256='MHJYVThihUrJcxW6wcqyOISTXIsInsdj3xK8QrZbHec='; pin-sha256='isi41AizREkLvvft0IRW4u3XMFR2Yg7bvrF7padyCJg='; includeSubdomains; max-historic period=2592000" always;                  

Apache:

          Header ever fix Public-Key-Pins "pin-sha256='X3pGTSOuJeEVw989IJ/cEtXUEmy52zs1TZQrU06KUKg='; pin-sha256='MHJYVThihUrJcxW6wcqyOISTXIsInsdj3xK8QrZbHec='; pivot-sha256='isi41AizREkLvvft0IRW4u3XMFR2Yg7bvrF7padyCJg='; includeSubdomains; max-age=2592000"                  

IIS:


X-Frame-Options

The X-Frame-Options header (RFC), or XFO header, protects your visitors against clickjacking attacks. An attacker can load up an iframe on their site and set your site equally the source, it'southward quite easy: <iframe src="https://scotthelme.co.uk"></iframe>. Using some crafty CSS they tin can hide your site in the background and create some genuine looking overlays. When your visitors click on what they call back is a harmless link, they're actually clicking on links on your website in the background. That might non seem then bad until we realise that the browser volition execute those requests in the context of the user, which could include them existence logged in and authenticated to your site! Troy Hunt has a dandy blog on Clickjack attack – the subconscious threat right in front end of y'all. Valid values include DENY significant your site can't be framed, SAMEORIGIN which allows you to frame your ain site or ALLOW-FROM https://example.com/ which lets you specify sites that are permitted to frame your ain site.

NginX:

          add_header Ten-Frame-Options "SAMEORIGIN" always;                  

Apache:

          Header always set X-Frame-Options "SAMEORIGIN"                  

IIS:

IIS XFO Header


X-Xss-Protection

This header is used to configure the built in cogitating XSS protection found in Internet Explorer, Chrome and Safari (Webkit). Valid settings for the header are 0, which disables the protection, 1 which enables the protection and 1; mode=block which tells the browser to block the response if information technology detects an set on rather than sanitising the script.

NginX:

          add_header X-Xss-Protection "1; manner=block" e'er;                  

Apache:

          Header ever set 10-Xss-Protection "1; way=block"                  

IIS:

IIS XXSS Header


X-Content-Type-Options

Nice and easy to configure, this header only has one valid value, nosniff. It prevents Google Chrome and Internet Explorer from trying to mime-sniff the content-type of a response abroad from the ane existence declared by the server. Information technology reduces exposure to drive-by downloads and the risks of user uploaded content that, with clever naming, could be treated as a dissimilar content-type, like an executable.

NginX:

          add_header Ten-Content-Type-Options "nosniff" ever;                  

Apache:

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

IIS:

IIS XCTO Header


Removing Headers

The adjacent stride in hardening your HTTP response headers is looking at the headers that yous can remove to reduce the amount of data you're divulging about your server and what's running on it. Servers will normally reveal what software is running on them, what versions of the software are on there and what frameworks are powering it. Reducing the corporeality of information you divulge is e'er a do good. I will look over some of the near common headers just yous tin can always examine your own sites HTTP response headers to meet if there are any more than that yous can remove using SecurityHeaders.io.


Server

The Server header is the most common header you volition probable see on a site. Defined in the RFC


The Server response-header field contains information about the
software used by the origin server to handle the asking. The field
can contain multiple product tokens (department 3.8) and comments
identifying the server and whatsoever significant subproducts. The product
tokens are listed in order of their significance for identifying the
application.

Designed to give information about the particular Web Server application being run on the server, common values signal to Microsoft IIS, NginX or Apache. However, the RFC does go on to land


Note: Revealing the specific software version of the server might
allow the server motorcar to become more than vulnerable to attacks
against software that is known to contain security holes. Server
implementors are encouraged to make this field a configurable
pick.

Despite that, many vendors don't arrive that easy to change the value of the header or, ideally, remove it completely.

IIS Server Header

NginX Server Header


IIS

For IIS, this looks a little long winded, simply it's just a lot of pictures really! The get-go thing you need is the URL-Rewrite extension. Once installed, caput to the IIS Manager and select your site, and then URL Rewrite.

IIS URL Rewrite

Select Server Variables and so add a new Server Variable called RESPONSE_SERVER.

View server variables

Add new server variable

RESPONSE_SERVER variable

Once yous have your new server variable, go back to the rules page, add a new rule and select a blank outbound dominion.

Back to rules

Add a new rule

Blank outbound rule

Give the rule a name, set the Matching Telescopic to Server Variable, the Variable name is RESPONSE_SERVER and fix the Blueprint to .* to match whatever content. Hit Apply to create your new rule.

New rule content

These changes will now remove the content of the Server response header, so it will expect something like this.

Blank Server Header

If you lot like, you can edit the rule and roll farther downward to give the header some content.

Give the header some content

Header with a value


NginX

Unfortunately, changing the value of the Server header on NginX isn't quite that like shooting fish in a barrel. You will need to download the NginX source, make 2 changes and then compile it.

          cd ~ wget http://nginx.org/download/nginx-1.7.x.tar.gz tar -xzvf nginx-1.seven.10.tar.gz nano nginx-i.7.10/src/http/ngx_http_header_filter_module.c                  

Once you take the source file open up, y'all need to brand the following changes, from this:

NginX HTTP Header Source

To this:

NginX HTTP Header Source Modified

Once you've made the changes and saved them you will need to compile and install NginX. My blog on how PageSpeed contains data on how to compile NginX from source so I won't duplicate the information here.

Update: Y'all can also use the server_tokens directive set to off in your nginx config or your vhost file. The directive can exist ready in the http, server or location context and will simply reduce the Server header to the value "nginx". It'due south not quite as effective as completely irresolute the header merely doesn't require you to compile nginx from source.

          server {     ...     server_tokens off; }                  

X-Powered-By

The 10-Powered-By header gives data on the technology that's supporting the Web Server. With typical values like ASP.Cyberspace or PHP/5.4.0, this is another slice of information that nosotros can remove from public display.


ASP.Internet

At that place are ii possible means you tin remove or alter the 10-Powered-By header in IIS. The first, and easiest way is to check in the HTTP Response Headers department.

Response Headers

If the X-Powered-Past header is nowadays here, you can simply modify it's value or remove it.

Remove X-Powered-By

The 2nd method, like the server header, is to use the URL Rewrite module to remove or modify the value. Follow the same steps for the server header, but substitue out the proper name of the server variable and the details in the creation of the dominion.

Add X-Powered-By Variable

X-Powered-By Rule

As before, that will either strip the content of the header or insert your custom content if you define any.


PHP

Nice and like shooting fish in a barrel in PHP, all we need to do is edit one line of config and restart PHP.

          sudo nano /etc/php5/fpm/php.ini                  

Locate the following line and alter it from this:

          expose_php = On                  

To this:

          expose_php = Off                  

Save the changes to your ini file and restart PHP.

          sudo service php5-fpm restart                  

X-AspNet-Version

The 10-AspNet-Version header pretty much just does what it says on the tin. It discloses the specific version of Asp.NET you're running, so it has to go! Some other really easy header to get rid of, it only requires a minor change in your web.config file.

          <organization.web> <httpRuntime enableVersionHeader="false" /> </system.web>                  

After you lot've saved the changes, restart your site for them to accept impact.


Checking your headers

You can use the programmer tools in your browser to cheque your HTTP response headers, or head over to SecurityHeaders.io and browse your site to bank check them. You volition go some dainty feedback on the headers that are present and any that are missing that you could implement. Go on a regular cheque on your own site and sites that you visit to see if annihilation unexpected crops up in the future!