HTTP Security Headers: A simple way to improve your web application security
What are HTTP security headers?
Modern browsers support an array of HTTP headers that pass additional information between the client and server when they perform a request or receive a response.
HTTP security headers are a subset of headers that are given to the client by the server. The client uses these to provide extra layers of privacy and security by validating the directives set in the headers. Each header helps protect the web application and its users from Man-in-the-Middle attacks, Cross-Site Scripting (XSS), Cross-Site Request Forgery, Click-jacking and other common attacks.
Recommended HTTP security headers
There are a handful of security headers that should be implemented across all applications as a standard practice. Below are the HTTP security headers that we recommend you implement to improve your web application security and protect its users.
HTTP Strict Transport Security (HSTS)
The Strict-Transport-Security
header helps to protect against Man-in-the-Middle attacks such as Protocol Downgrade Attack and Cookie Hijacking. It does this by enforcing the implementation of TLS across all connections of your web application and ensuring subsequent requests are made using HTTPS.
X-Frame-Options
The X-Frame-Options
header can help to protect against Click-jacking. It does this by informing the web browser whether or not it should allow your web application to be framed/rendered in a <frame>, <iframe>, <embed> or <object>
. This can also be enforced using the frame-ancestors policy in the Content-Security-Policy.
There are 2 recommended directives:
DENY
- (Recommended the most) the web application cannot be displayed in a frame regardless of the site requesting it.
SAMEORIGIN
- The web application can only be displayed in a frame of the same origin as itself.
Content-Security-Policy
The Content-Security-Policy
header should be used to protect your web application from Cross-Site Scripting (XSS) attacks. It does this by defining approved sources that a user’s browser can load. Any injected scripts or code that has not been approved by the headers directives will be blocked.
A recommended example of this header cannot be given as the required policies and directives are distinctive of your web application, however, below are some dos and don’ts when implementing this.
- Remember this header aims to make your site functional for only itself and your selected third parties securely.
default-src
is the primary policy that browsers will fall back to. In 98% of scenarios, this should be set to ‘none’, it is good practice and it should enforce you to turn on only the policies that you require.- Avoid using
‘unsafe-inline’
or‘unsafe-eval’
unless you have no other choice. In these situations, try to implement a‘nonce-’
or‘sha-256’
directive. - Run an end-to-end test to ensure that this header does no hinder your application’s functionality.
As an example, a site that uses Google Font and Google Maps should look like this,
It is worth noting, out of all of the security headers listed in this article, the Content-Security-Policy
header is the longest to implement due to its trial and error implementation. See content-security-policy.com for more information on how to implement this header and what each policy and directive affects.
X-XSS-Protection
The X-XSS-Protection
header is intended for older browsers (IE 8, Safari and Chrome) to help protect your web application from Cross-Site Scripting (XSS) attacks. For modern browsers, you should look at the Content-Security-Policy
header, however, it is good practice to include.
X-Content-Type-Options
The X-Content-Type-Options
header stops the browser from trying to MIME-sniff the content-type. It does this by forcing the browser to stick with the declared content-type. Reducing the risk of user-uploaded content from being treated as a different content-type.
Referrer-Policy
The Referrer-Policy
header helps with user privacy. It controls how much information the browser should include when navigating away from the web application. Without this, websites can get a hold of which page the user was referred from. This is referrer information is gold dust in the tracking world such as Google Analytics and Facebook, however, depending on your web application and tracking requirements, the privacy of the user should be upheld as much as possible.
There are 3 recommended directives:
no-referrer
- As described, this value will instruct the browser not to send referrer information in requests.
https://gravitywell.co.uk/example1 > https://gravitywell.co.uk/example2 will pass NULL
.
https://gravitywell.co.uk/example1 > http://gravitywell.co.uk/example2 will pass NULL
.
https://gravitywell.co.uk/example1 > https://example.com will pass NULL
.
https://gravitywell.co.uk/example1 > http://example.com will pass NULL
.
strict-origin
- The browser will always send referrer information as a full URL in requests if the request has the same origin (domain) over HTTPS. If the HTTP protocol changes to HTTP then no referrer information will be set (NULL
).
https://gravitywell.co.uk/example1 > https://gravitywell.co.uk/example2 will pass https://gravitywell.co.uk/example1.
https://gravitywell.co.uk/example1 > http://gravitywell.co.uk/example2 will pass NULL
.
https://gravitywell.co.uk/example1 > https://example.com will pass NULL
.
https://gravitywell.co.uk/example1 > http://example.com will pass NULL
.
strict-origin-when-cross-origin
- Similar to the strict-origin
directive, however, when navigating away from the original origin to another website the URLs pathname will be removed.
https://gravitywell.co.uk/example1 > https://gravitywell.co.uk/example2 will pass https://gravitywell.co.uk/example1.
https://gravitywell.co.uk/example1 > http://gravitywell.co.uk/example2 will pass NULL
.
https://gravitywell.co.uk/example1 > https://example.com will pass https://gravitywell.co.uk/.
https://gravitywell.co.uk/example1 > http://example.com will pass NULL
.
Permissions-Policy
The Permissions-Policy
header helps improve the security and privacy of the user by enabling or disabling certain browser features and APIs. This can benefit the user if a malicious script attempts to exploit them and their data using certain browser features and APIs.
If your web application requires certain features like geolocation, you can set this policy to only allow itself and trusted third parties to access it.
Tooling
Check out securityheaders.com for a fast and simple way to validate your web application’s security headers. It gives informs you on how secure your application is using an A - F grade system. It also gives you an in-depth summary of what you will need to implement if you wish to improve its security.
Another gem is ssllabs.com/ssltest, for its ability to inform you just how secure your SSL configuration is. It also lets you know if the SSL connection is effective enough against certain attacks. It gives you an in-depth summary of what you will need to implement if you wish to improve your SSL configuration.
These tools will evolve as security specifications change. So will this article, watch this space for changes in our recommendations and make sure that you use these in your everyday practice to ensure your web application’s privacy, security and compliance.
While these HTTP security headers can be simple to implement, we recommend that you implement them in the early stages of development to ensure any gotchas do not hinder the final functionality of your application.