Sometimes security can represent a heavy investment in terms of web development.
But there are some tiny adjustments that you can implement on your website that will help you making substantial progress in security. In fact these adjustments are really small in terms of code and configuration, but have a significant impact that requires proper analysis and validation before being implemented.
Here is how HTTP headers can help you in your security efforts.

Better than just rewriting technical specifications and explaining all the details of these HTTP headers, we will focus on giving you a synthetic analysis and a list of interesting links you would like to browse if you need further details.
One important thing to keep in mind is that these headers have an impact on the browser side. They control how web browsers must behave (if they implement the corresponding functionalities). They do not modify the server’s behavior.

We will review the following security-related headers:

  • Strict-Transport-Security
  • CORS headers (Access-Control-Allow-Origin)
  • Content-Security-Policy
  • X-Content-Type-Options
  • X-XSS-Protection
HTML code

Strict-Transport-Security

Also called HSTS (HTTP Strict Transport Security), this header ensures that communications between the web browser and the web server will be over HTTPS.
In a nutshell, once the web browser receives this header from the server, it will not send HTTP request to the server, but keep on using HTTPS. If a link or a content is using HTTP, it will be upgraded to HTTPS.

Strict-Transport-Security: max-age=31536000

The above header instructs the browser to use the STS option, and remember it for one year.

Although simple to implement, this header is very powerful and can sometimes bring problems : What happens if a part of your website is not served under HTTPS (technically) and browsers are instructed to communicate over a secure channel? Be cautious with the header options : you can choose to include all sub-domains, but do you really want to?

From an attack perspective:

Implementing this header mitigates MITM attacks (Man In The Middle) where an attacker could steal data over a clear communication channel (HTTP), through downgrading attacks.
It also covers issues where a website is supposed to be fully served over HTTPS and mistakenly contains HTTP links or contents : HTTP requests are automatically converted to HTTPS.

IETF specifications : https://tools.ietf.org/html/rfc6797
Wikipedia page : http://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security

Browser support:

Internet Explorer : NO (being implemented, planned for V12)
Firefox : YES (since V4)
Chrome : YES (since V4)
Safari : YES (since V7)

For a full compatibility list : http://caniuse.com/#search=strict%20transport%20security

CORS headers (Access-Control-Allow-Origin)

CORS (Cross Origin Resource Sharing) is a set of rules that allows different websites on different domains to interact in a way that is not permitted by the Same Origin Policy.
As a reminder, the same origin policy has been put in place in order to avoid security issues where a malicious website could make requests (through the browser) to another website, like a bank website allowing an attacker to retrieve the content of a page from the bank website.

However this Same Origin Policy is very strict and limiting for some use cases, where two websites hosted on different domains would need to communicate (on the front-end side, not server-side).
The CORS mechanism has therefore been introduced to relax this policy and allows developers to specify on THEIR web application which other domains are allowed to make requests to THEIR web application.

CORS includes several headers, on the request side :
Origin
Access-Control-Request-Method
Access-Control-Request-Headers

And on the Response headers :
Access-Control-Allow-Origin
Access-Control-Allow-Credentials
Access-Control-Expose-Headers
Access-Control-Max-Age
Access-Control-Allow-Methods
Access-Control-Allow-Headers

From an attack perspective:

These headers, if not properly configured, can be an open door for attackers. If for example a too permissive policy has been configured (with Access-Control-Allow-Origin: * ), then any website can retrieve the content of a page on the target website. This is not a problem on websites containing fully public data, of course.
These headers are a key to open doors, use it with caution!
W3 resource : http://www.w3.org/TR/cors/
Wikipedia page : http://en.wikipedia.org/wiki/Cross-origin_resource_sharing

Browser support:

Internet Explorer : YES (partial since 8, full since 10)
Firefox : YES (since V3.5)
Chrome : YES (since V4)
Safari : YES (since V4)

For a full compatibility list : http://caniuse.com/#search=cors

Content-Security-Policy

Unlike the CORS mechanism, the CSP allows you to define which domains your website is allowed to make requests TO (and thus retrieve content from).
The scope of the policy includes scripts, form actions, frames, fonts, images, style sheets, plugins, and media (audio, video, text tracks…). This policy has been designed to mitigate Cross Site Scripting attacks.

Example:

Content-Security-Policy:
default-src ‘self’; img-src *;
object-src media.vaadata.com;
script-src scripts.vaadata.fr

The above script specifies that the website can load images from anywhere, that plugins (objects) can only be loaded from media.vaadata.com and that scripts are allowed from scripts.vaadata.fr

From an attack perspective:

This policy mitigates Cross Site Scripting (XSS) attacks, which is a very good thing (for application defenders!).

W3 resource : http://www.w3.org/TR/CSP
Wikipedia page : http://en.wikipedia.org/wiki/Content_Security_Policy

Browser support (version 1):

Internet Explorer : YES (since V10 – partial)
Firefox : YES (since V4)
Chrome : YES (since V14)
Safari : YES (since V6)

For a full compatibility list : http://caniuse.com/#search=csp

X-Frame-Options

X-Frame-Options is one anti click-jacking solution.
When properly set, this header prevents your website from being loaded inside an iframe.

Note : X-Frame-Options is being implemented as part of the CSP (1.1 and 2). CSP2 will remain a Candidate Recommendation at least until July 2015.
In the meantime, the X-Frame-Options can still be used.

The header accepts 3 different values : DENY, SAMEORIGIN, ALLOW-FROM. If you don’t want your page to be loaded via iframe, simply use the DENY directive.

Example:

X-Frame-Options: DENY

IETF specifications: http://www.ietf.org/rfc/rfc7034.txt

Browser support:

Internet Explorer : YES (since V8)
Firefox : YES (since V3.6)
Chrome : YES (since V4)
Safari : YES (since V4)

The ALLOW-FROM is not supported by all browsers, however, and does not seem trustworthy.

X-Content-Type-Options

When configured, this header instructs web browsers to strictly follow MIME types provided by the server, and not to MIME-sniff responses away from the declared content-type. As an example, a stylesheet will only be loaded if the MIME type is “text/css”.

Letting browsers guess what type of content is returned by the server can lead to serious security issues. A malicious user can use this vulnerability to have your server return dangerous content to your legitimate users. Web browsers take the contents they receive from the server and use them in a different manner, depending on the provided MIME type. If there is no MIME type or an incorrect one, the browser will decide by itself what to do with that content and will potentially execute malicious code.

That’s why you should clearly define the MIME type of all contents returned by your server, and tell web browsers not to guess content types. Before implementing this header, you must verify that all your web contents are served with the right MIME type, this is very important (otherwise the content will be blocked).

The header is easy to implement, it take only one possible value: nosniff.

Browser support:

Internet Explorer : YES (since V9)
Firefox : YES
Chrome : YES
Safari : YES

X-XSS-Protection

Initially designed by Microsoft, this header is now implemented on Internet Explorer and Chrome.
The objective, as the name suggests, is to protect users against XSS attacks.

A few options are available:

X-XSS-Protection 0 : Disables the protection
X-XSS-Protection 1 : Enables the protection
X-XSS-Protection 1; mode=block : Protection enabled, the browser will block the attack, instead of sanitizing the malicious content.
X-XSS-Protection 1; report=http://URL-FOR-REPORT This option, specific to Chrome, will POST attacks to the provided URL.

Note : This header is now deprecated and should be replaced by the Reflected-XSS directive, inside CSP.

Browser support:

Internet Explorer : YES
Firefox : NO
Chrome : YES
Safari : NO