During the last few years, a number of new HTTP headers have been introduced whose purpose is to help enhancing the security of a website. Some of these headers can be very useful protection against certain type of attacks, but their use is not widely spread in some cases. This blog post is an attempt to explain how these headers work, the main purpose of each of them, and to show a few examples that will hopefully serve as a guide for real world implementations.
Content security policy (CSP) was designed to allow the owners of a web application to inform the client browser about expected behaviour of the application (including content sources, script sources, plugin types, and other remote resources), which allows the browser to more intelligently enforce security constraints. Although CSP is complex in nature, and it can get messy if not deployed appropriately, a well-applied CSP can drastically decrease the chances of exploitation of most forms of cross-site scripting attacks.
An entire post would be needed to dive into the features and different settings CSP allows, therefore further reading is advised. The following is an excellent introductory post to CSP by the Mozilla Developer Network: https://developer.mozilla.org/en-US/docs/Web/Security/CSP
The brief example below shows how CSP could be used to specify that your website wishes to load images from any URI, plugin content from a list of trusted media providers (including a content distribution network), and scripts only from a server under your control:
Content-Security-Policy: default-src ‘self’; img-src *; object-src media1.example.com media2.example.com *.cdn.example.com; script-src trustedscripts.example.com
Please note that the main issues with the use of CSP relate to policy misconfigurations (i.e. using “unsafe-inline”), or to the use of too permissive policies, and therefore careful attention should be paid when implementing CSP.
The Strict Transport Security (HSTS) header is used to force browsers to only communicate with the server over a secure connection. If HSTS is in place, the browser will not allow you to access the website over HTTP. Additionally, HSTS prevents the client from overriding an SSL certificate warning that could be presented if the website certificate is invalid, or if a fake certificate is presented to the client by an attacker.
The HSTS response header should only be sent over a secure transport layer and browsers should ignore this header if received over HTTP. This is primarily because an attacker running a man in the middle (MiTM) attack could maliciously strip out or inject this header into a HTTP response causing undesired behaviour. This, however, does present a very slim window of opportunity for an attacker in a targeted attack. Upon a user’s very first interaction with a website, the browser will have no knowledge of a HSTS Policy for the host; this will result in the first communication taking place over HTTP and not HTTPS. To combat this bootstrapping problem, many browsers contain a preloaded list of sites that are configured for STS.
HSTS is very easy to configure, and it is commonly set to a “max-age” value high enough to ensure the website is cached in the HSTS list for the defined period. The following server response is an example of a HSTS header being set to cache the domain in the HSTS list for one year:
All major modern browsers currently support HTTP Strict Transport Security, except for Opera Mini and versions of Internet Explorer prior to 11.
Where a website can be embedded in an IFRAME element, an attacker could socially engineer a situation where a victim is directed to a website under an attacker’s control that frames the target website. The attacker could then manipulate the victim into unknowingly performing actions on the target website. This attack is possible even with cross-site request forgery protection in place, and is known as “clickjacking”, for more information please refer to https://www.owasp.org/index.php/Clickjacking. In order to avoid this, the “X-Frame-Options” header was created. This header lets the owner of the website decide which sites are allowed to frame their site.
The common recommendation is to set this header to either “SAMEORIGIN”, which allows only resources which are part of the Same Origin Policy to frame the protected resource, or to “DENY”, which denies any resource (local or remote) from attempting to frame the resource that also supplied the “X-Frame-Options” header. This is shown below:
Please, note that the “X-Frame-Options” header has been deprecated and will be replaced by the Frame-Options directive in the Content Security Policy, which is still under active development. However, the “X-Frame-Options” header currently has much wider support, and as such should still be implemented a security measure.
Modern browsers include a feature to help prevent against reflected cross-site scripting attacks, known as the XSS Filter. The “X-XSS-Protection” header can be used to enable or disable this built-in feature (this is only supported in Internet Explorer, Chrome and Safari currently).
The recommended configuration is to set this header to the following value, which will enable the XSS protection and instruct the browser to block the response in the event that a malicious script has been inserted from user input, instead of sanitizing:
X-XSS-Protection: 1; mode=block.
Internet Explorer and Chrome will sanitize any malicious data by default, if no “X-XSS-Protection” header is sent from the server.
Please, note that the X-XSS-Protection header has been deprecated and will be replaced by the Reflected-XSS directive in the Content Security Policy, which is still under active development. However, the “X-XSS-Protection” header currently has much wider support, and as such should still be implemented a security measure.
A nifty attack known as MIME type confusion was the reason this header was created. Most of the browsers employ a technique called MIME sniffing, that consists on taking an educate guess at what the content type of the server response is, instead of trusting what the header’s content type value says. Under certain circumstances, browsers can be tricked into making the incorrect decision, allowing attackers to execute malicious code on victim’s browsers. For more information please refer to https://en.wikipedia.org/wiki/Content_sniffing.
“X-Content-Type-Options” can be used to prevent this “educated” guess from happening by setting the value of this header to “nosniff”, as shown below:
Please, note that Internet Explorer, Chrome and Safari have support for this header, but the Firefox team is still debating it:https://bugzilla.mozilla.org/show_bug.cgi?id=471020
As an example of this header, to permit https://www.dionach.com to request and integrate your site’s data and content would be the following:
The use of a wildcard (*) is allowed, but not generally recommended. There have been some modifications in the CORS standard since it was created, and as defined in the latest version, “when responding to a credentialed request, server must specify a domain, and cannot use wild carding.”. This means that a response from the server containing a wildcard and allowing the use of credentials will not be accepted by modern browsers.
For a more detailed explanation of all the headers that are part of the CORS standard, and how they all work, please refer to the following resource: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
It is recommended that you do not set any CORS related headers unless you are sure you want to allow requests from other websites you do not control. A website that does not set any CORS headers, will not allow requests from any other sites.