HTTP Headers play a very important role in security of a web application. Some of the headers pose a security risk and so should be removed while others help prevent against different kinds of attacks so should be added.
Following are same best practices with respect to HTTP headers.
Remove headers revealing too much information about server
Revealing information about server increases your attack surface and makes the attacker job easier in case a vulnerability is found on the given server. These headers usually do not add any value to the application so they should better be turned off. Following are some headers for Aspnet MVC application that can safely be stripped.
- X-AspNet-Version: It can be easily stipped in web.config as follows.
<system.web> <httpRuntime enableVersionHeader="false" /> </system.web>
- X-AspNetMvc-Version: It can be easily stripped in global.asax application_start as follows.
MvcHandler.DisableMvcResponseHeader = true;
- X-Powered-By: It can be stripped in web.config as follows.
<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<clear />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>
- Server: This is a little bit tricy to remove. This is written by IIS and it is not very safe to try to remove it from with Asp Net. It can removed using Http Modules but is not recommended using article here. A better approach is to use UrlScan as mentioned by Troy Hunt here.
Add Security Headers
There are several security headers recommended in the Http sepc and implemented by many browsers that should be leveraged as a layer of defense aganst verious kinds of attacks. Here are some headers that can be used.
- HTTP String Transport Security (HSTS): HSTS instructs the browser that you only want to load secure version of that site. This reduces impact of bugs in application leaking session data through cookies and external links and defends against Man-in-the-middle attacks. HSTS also disables the ability for users to ignore SSL negotiation warnings.
Strict-Transport-Security: max-age=16070400; includeSubDomains;preload
HSTS suffers from what is called Trust-on-first-use (TOFU) because the site must be loaded first in order to get the HSTS header. So you do have small risk window when the site is loaded over an unsecure connection. ‘preload’ is used to solve exactly this problem. This is still a pretty new concept and not many websites are using this. You have to register your domain to preload list
here. More details on HSTS
here.
- HTTP Public Key Pinning (HPKP): HPKP allows public certificates to be whitelisted to protect in case you CA (Certificate Authority) is compromised and so someone else can actually present a forged certifficate on your behalf.
Public-Key-Pins: pin-sha256="<sha256>"; pin-sha256="<sha256>"; max-age=15768000; includeSubDomains
You should create backup pins and short max age to mitigate risk like expired certificate, etc. More details on HKPK here.
- Content Security Policy (CSP): CSP s a way of whitelisting what your site is allowed to run. It is quite comprehensive and contains many directive. You can control your script sources, stylesheet sources, font sources, etc. Following is content security policy that Facebook sends as of today.
content-security-policy:default-src * data: blob:;script-src *.facebook.com *.fbcdn.net *.facebook.net *.google-analytics.com *.virtualearth.net *.google.com 127.0.0.1:* *.spotilocal.com:* 'unsafe-inline' 'unsafe-eval' fbstatic-a.akamaihd.net fbcdn-static-b-a.akamaihd.net *.atlassolutions.com blob: chrome-extension://lifbcibllhkdhoafpjfnlhfpfgnpldfl;style-src * 'unsafe-inline' data:;connect-src *.facebook.com *.fbcdn.net *.facebook.net *.spotilocal.com:* *.akamaihd.net wss://*.facebook.com:* https://fb.scanandcleanlocal.com:* *.atlassolutions.com attachment.fbsbx.com blob: 127.0.0.1:* http://*.serialpodcast.org https://*.serialpodcast.org;
More details on Content Security Policy here.
- X-Frame-Options: To improve the protection of web applications against Clickjacking attack this directive tells the browser what is the allowed policy on whether this site can be hosted inside iFrame of another website. Valid values are deny, sameorigin and allow-from.
X-Frame-Options: deny
- X-XSS-Protection: This header enables Cross Site Scripting filter built into most recent web browsers. This is not widely suppoted by all browsers but as with all security measures, there is no harm in adding another level of defense.
X-XSS-Protection: 1; mode=block
- X-Content-Type-Options: The only defined value, "nosniff", prevents Google Chrome and Internet Explorer from trying to mime-sniff the content-type of a response away from the one being declared by the server. It reduces exposure to drive-by downloads and the risks of user uploaded content that, with clever naming, could be treated as a different content-type, like an executable.
X-Content-Type-Options: nosniff
It is not trivial to manage so many headers and be able to correctly set them. You shoudl prefer some library that can do this job for you. One such very good library for Aspnet is
NWebSec.