Friday, 30 March 2012

Seven Web Server HTTP Headers that Improve Web Application Security for Free

We deal with clients and teams of all maturity levels here at Recx. They range from those who understand risk and want deep level expertise to those who are just realising they need security (typically after an incident) and need to get to grips with the basics.

As it's Friday we're going to take a step back from the low level and focus on some web basics. We've had our Chrome extension that checks for web server headers that improve security available since August 2011. This is a tool really designed for anyone. Be they a developer, quality assurance tester or security professional . It's designed to make sure we're all getting the basics right. Today we're going to look at the web server headers it checks for.

What follows is an explanation of each of the headers we check for, the text is mainly lifted from the Chrome extension if you get weird sense of deja vu.

The 'X-Content-Type-Options' HTTP header if set to 'nosniff' stops the browser from guessing the MIME type of a file via content sniffing. Without this option set there is a potential increased risk of cross-site scripting

Secure configuration: Server returns the 'X-Content-Type-Options' HTTP header set to 'nosniff'.

The 'X-XSS-Protection' HTTP header is used by Internet Explorer version 8 and higher. Setting this HTTP header will instruct Internet Explorer to enable its inbuilt anti-cross-site scripting filter. If enabled, but without 'mode=block' then there is an increased risk that otherwise non exploitable cross-site scripting vulnerabilities may potentially become exploitable. 

Secure configuration: Server returns the 'X-XSS-Protection' HTTP header set to '1; mode=block'.

The 'X-Frame-Options' HTTP header can be used to indicate whether or not a browser should be allowed to render a page within a <frame> or <iframe>. The valid options are DENY, to deny allowing the page to exist in a frame or SAMEORIGIN to allow framing but only from the originating host. Without this option set the site is at a higher risk of click-jacking unless application level mitigations exist. 

Secure configuration: Server returns the 'X-Frame-Options' HTTP header set to 'DENY' or 'SAMEORIGIN'.

The 'Cache-Control' response header controls how pages can be cached either by proxies or the user's browser. Using this response header can provide enhanced privacy by not caching sensitive pages in the users local cache at the potential cost of performance. To stop pages from being cached the server sets a cache control by returning the 'Cache-Control' HTTP header set to 'no-store'.

Secure configuration: Either the server sets a cache control by returning the 'Cache-Control' HTTP header set to 'no-store, no-cache' or each page sets their own via the 'meta' tag for secure connections.

Updated: The above was updated after our friend Mark got in-touch. Originally we had said no-store was sufficient. But as with all things web related it appears Internet Explorer and Firefox work slightly differently (so everyone ensure you thank Mark!).

The 'X-Content-Security-Policy' response header is a powerful mechanism for controlling which sites certain content types can be loaded from. Using this response header can provide defence in depth from content injection attacks. However it's not for the faint hearted in our opinion.

Secure configuration: Either the server sets a content security policy by returning the 'X-Content-Security-Policy' HTTP header or each page sets their own via the 'meta' tag

The 'HTTP Strict Transport Security' (Strict-Transport-Security) HTTP header is used to control if the browser is allowed to only access a site over a secure connection and how long to remember the server response for thus forcing continued usage.

Note: This is a draft standard which only Firefox and Chrome support. But it is supported by sites such as PayPal. This header can only be set and honoured by web browsers over a trusted secure connection. 

Secure configuration: Return the 'Strict-Transport-Security' header with an appropriate timeout over an secure connection.

The 'Access Control Allow Origin' HTTP header is used to control which sites are allowed to bypass same origin policies and send cross-origin requests. This allows cross origin access without web application developers having to write mini proxies into their apps.

Note: This is a draft standard which only Firefox and Chrome support, it is also advocarted by sites such as

Secure configuration: Either do not set or return the 'Access-Control-Allow-Origin' header restricting it to only a trusted set of sites.

Not a header, but the end of this post. We hope you've found this introduction useful. As for how to set the headers in your application, application server, embedded appliance or web server that is an exercise for the reader / the subject of another blog post or five we suspect.

For those buying 'web based' products, services or appliances and finding these headers not being set it can in our experience be indicative that the vendor or service provider isn't really up on web security and is probably worth a closer look.


  1. Some people on my team are working on getting another header into standards that would extend this list: 'Public-Key-Pins'

    It would enable web servers to restrict the set of acceptable root CAs to which their SSL certificates can chain. The hard-coded set of roots for certs in Chrome is how Iran's MITM activity was detected last year and ultimately the Diginotar breach was added: this header would allow the benefits of cert-pinning to be available to all SSL web sites.

  2. This one goes here as well.

    And CSP in general.