HTTP Security Headers - How to improve your web application overall security with just a few steps
HTTP Security Headers were created to protect applications from frequent and common attacks without the need to add or change the code of your applications.
In the HTTP Protocol, we use headers both in our requests and responses to exchange information between the client and the server. Things like which browser the user is running, if they have a valid session already or to verify the origin of the request. Of course those values can be tampered, as well as headers can be added or removed, since they are just text.
To prevent some common attacks like XSS [CWE-79], Session Hijacking [CWE-384], Man-in-the-Middle, some specific headers were created. And when they are configured properly they automatically prevent web applications from these attacks. These headers are usually called Security Headers and it’s about them that we are going to discuss in our article today.
Security Headers are response headers, meaning that they are sent in the HTTP Response by the server, and you can easily use them to increase the overall security of your web applications. Many web servers such as Apache HTTPd, Microsoft IIS, Nginx already support these security headers that can be configured and activated within just a few steps. And don’t worry if they don’t support it, it won’t affect any function of your application, they’ll just ignore it.
We won’t go into details about all the Security Headers in this post, but mainly the most important ones that you should have activated on your web application. Let’s start, here are the Security Headers that we are going to talk about:
- HTTP Strict Transport Security (HSTS)
HTTP Strict-Transport-Security (HSTS)
As the name of the header already says it all, this header enforces the use of encryption (TLS) on all requests preventing against attacks such as protocol downgrade and cookie/session hijacking. It also makes it virtually impossible for the website to transmit any content over HTTP (mixed content). The header also checks the certificate features to avoid certain attacks like Man-in-the-Middle (MitM). Unfortunately you can only enable this header on applications that are full HTTPS already, otherwise it might break them or they won’t work properly. Just be careful and run some tests before activating it on production environments and you will be safe and sound.
HSTS has two main attributes:
- max-age = the time, in seconds, that the browser should remember that this site is only to be accessed using HTTPS; (usually a high value like the example below when the site should always be accessed over HTTPS)
- includeSubDomains = defines whether subdomains will honor this header, if specified. No value needed.
Here is a basic example of the HSTS Header:
Content Security Policy (CSP)
This header implements policies to protect against content injection attacks such as Cross-Site Scripting (XSS) and other data injection attacks. It is one of the most underused or misused HTTP Security Headers. Since this header can be a bit difficult to configure, most of the websites that use it, are using it wrong. If you restrict too much, you can break the application, and if you let it to loose, it is almost the same as not having one.
CSP has a large number of directives that should be analyzed carefully to implement an appropriate policy, but the basic use is that if the resource is not from the same source as the website, don’t allow it. We won’t go into details about all the directives for this header, but you can check them all here. Here’s an example of a basic CSP policy:
What this Security Header does is basically to prevent browsers from interpreting page content and executing the data as code. According to Wikipedia the technique Content Sniffing also known as MIME Sniffing is the practice of inspecting the content of a byte stream to attempt to deduce the file format of the data within it. With this header in place the only directive available is the nosniff one, preventing the browser from doing that. Here is the basic example of how to use it:
Well, the name of this header seems pretty obvious right? Can you guess what it does? You guessed right! It informs the browsers that anti-XSS filters should be applied. Since XSS is still very common on all web applications, modern browsers have tools that seek to filter page content by preventing Cross-Site Scripting (XSS) attacks from affecting users. Here is a basic example of how to use it:
This enables the XSS filter from the browser and when a XSS attack is detected, the browser prevents from rendering that page. For more options on how to use this header, please check this OWASP Secure Header Project page.
This header controls which content the browser can render from external content on DOM (Document Object Model) objects such as <frame>, <iframe> or <object>. These objects are usually used by attackers to perform Clickjacking attacks such as misleading buttons found on unsafe websites. It has three main options:
- deny - which denies rendering from frames of any kind
- sameorigin - only renders if the frame is from the same origin of the site
- allow-from: Domain - allows rendering if the frame is from that specific domain
Here is a basic example of how to use it on your webserver:
There are many more Security Headers that can be applied on your web applications. But make sure that you set up correctly the above mentioned security headers before going to the others.
Here at High-Tech Bridge we have a free application security tool called ImmuniWeb WebScan to check if your website has the CSP and other Security Headers implemented correctly, please check it out, it’s free! Here is a sample result of the scan on our own website:
ImmuniWeb® WebScan analyzes the following HTTP headers:
- Content-Security-Policy (also known as CSP)
- Public-Key-Pins (also known as HPKP)
- Strict-Transport-Security (also known as HSTS)
ImmuniWeb® WebScan also fingerprints your CMS and JS libraries, checks your website for crypto-jacking and other malware, and verifies if you website is protected by a WAF.
Try it now!