X-Content-Type-Options is a header that tells a browser to not try and “guess” what a mimetype of a resource might be, and to just take what mimetype the server has returned as fact.
At first this header seems kinda pointless, but it’s one of the simplest ways to block attack vectors that use javascript. For example, for a long time browsers were susceptible to a very popular JSON Array Vulnerability. The vulnerability essentially allowed an attacker to make your browser request a non-javascript file from a site, but run it as javascript, and in the process leak sensitive information.
For a long time, anything within a script tag like so :
<script type="text/javascript" src="http://somesite.com/not-a-javascript-file"></script>
Would be run as javascript, irrespective of whether the return content-type was javascript or not. With X-Content-Type-Options turned on, this is not the case and if the file that was requested to be run does not have the javascript mime-type, it is not run and you will see a message similar to below.
Refused to execute script from ‘http://somesite.com/not-a-javascript-file’ because its MIME type (‘application/json’) is not executable, and strict MIME type checking is enabled.
On it’s own the header might not block much, but when you are securing a site you close every door possible.
Another popular reason for using this header is that it stops “hotlinking” of resources. Github recently implemented this header so that people wouldn’t reference scripts hosted in repositories.
X-Content-Type-Options Settings
X-Content-Type-Options : nosniff
This is the only setting available for this header. It’s an on/off type header with no other “settings” available.
Setting X-Content-Type-Options At The Code Level
Like other headers, the easiest way is to use a custom middleware like so :
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { app.Use(async (context, next) => { context.Response.Headers.Add("X-Content-Type-Options", "nosniff"); await next(); }); app.UseMvc(); }
Setting X-Content-Type-Options At The Server Level
When running .net core in production, it is very unlikely that you will be using Kestrel without a web server infront of it (Infact you 100% should not be), so some prefer to set headers at the server level. If this is you then see below.
Setting X-Content-Type-Options in IIS
You can do this in Web.config but IIS Manager is just as easy.
- Open IIS Manager and on the left hand tree, left click the site you would like to manage.
- Double click the “HTTP Response Headers” icon.
- Right click the header list and select “Add”
- For the “name” write “X-Content-Type-Options” and for the value “nosniff”
Setting X-Content-Type-Options in Apache
In your httpd.conf file you need to append the following line :
Header always append X-Content-Type-Options nosniff
Setting X-Content-Type-Options in htaccess
Header append X-Content-Type-Options "nosniff"
Setting X-Content-Type-Options in NGINX
In nginix.conf add the following line. Restart NGINIX after.
add_header X-Content-Type-Options "nosniff";
For more information click here
Setting X-Content-Type-Options At The Code Level is working only when i am writing before app.UseMVC. This might helpful if any one gets in same situation like me.
Edited. The example I took this from had a bunch of middleware that I removed to copy and paste here, and I got the order mixed up.
In general, UseMVC should be the last middleware in your pipeline. Middleware runs in order, and it can “short circuit” and not run the subsequent middlewars at all.
>> it is very unlikely that you will be using Kestrel without a web server infront of it (Infact you 100% should not be)
True for 2017, but staring from aspnetcore 3.1 you may use Kestrel without proxy infront.
See https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel?view=aspnetcore-3.1#when-to-use-kestrel-with-a-reverse-proxy
>> Kestrel can be used by itself or with a reverse proxy server
True. I really need to go back and update some of these posts 🙂