Search This Blog

Monday, December 31, 2018

Web Security: what does mean by http header 'X-Content-Type-Options=nosniff' ?

Before going in details about this HTTP header, let's have a look into how the browser process the content type of a file received from the web server. Whenever a file received from the server by default browser determine its content type by checking the content of file irrespective of file extension and content-type header provided by the server(this is called content sniffing).

Example: Let's save the below HTML content as the zip file (test.zip)

<html>
   <head>
     <script
type="text/javascript" >
       alert("OK");
     </script>
   </head>
   <body>
   </body>
</html>


When you browse the file "test.zip" from your IE browser you will get an alert popup with message "OK" instead of downloading it eventhough the content-type sent by server is "application/x-zip-compressed" and extension is zip.



Now change the content of the file with some normal plain text and browse it. This time you will that it is prompting for download(see as below)



Now we can conclude here as per the above example that the browser does the content checking to decide the content type of the received file before rendering.

It means a channel is open for cross-site-scripting(XSS). Any attacker can play with the content of the file, hence the web application is vulnerable. To overcome on this vulnerability, first Microsoft introduced the below HTTP header with directive "nosniff" which tells the browser to not check the content type of the file and just trust content-type sent by the web server, and later the almost browser implemented this HTTP header.

X-Content-Type-Options : nosniff

Conlusion: To stop the browser from content sniffing, it is recommended to set your web server to return the HTTP header "X-Content-Type-Options : nosniff" in every response. This will prevent from cross-site-scripting(XSS)

Friday, December 28, 2018

Web Security: Why do we need http header "Strict-Transport-Security"?

Web Security: Why do we need to use http header "Strict-Transport-Security"? It is possible that a web site can allow user to access it via HTTP and HTTPS both. In this case user can browse the web site either using Http or using https, we can enforce the connection to use https instead of http by adding HSTS (HTTP Strict-Transport-Security ) policy in web site response header. This header tells browser to use Https even though the user is trying to access it through http. Lets achieve this in following way -

Add the below header in your web site response header -

Strict-Transport-Security: max-age=<expiry-time in seconds>; includeSubDomains; preload

  • max-age=<expiry-time in seconds>: Browser remember this expiry time, this can be any duration in second for days, months or years.
  • includeSubDomains[optional]: This is optional directive, its presence in this header tells browser to apply the same rule (hsts rule) for sub domains as well.
  • preload[optional]: This is optional and is not the part of the specification.

Technical Implementation:
  • In ASP.Net Core
    Use any of the below approach to implement hsts.
    Approach 1: Use inbuild Hsts middleware(default configuration). This implementation has the 30 days value into max-age parameter by default

    public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
    app.UseHsts(); }

    If you want to override the default setting, add below configuration as well
    public void ConfigureServices(IServiceCollection services)
    {
      services.AddHsts(options=>{
           options.Preload = true;
           options.MaxAge= TimeSpan.FromDays(365);//for one years
           options.IncludeSubDomains = true;
           options.ExcludedHosts.Add("example.com");
           options.ExcludedHosts.Add("www.example.com");
       });

      services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    }

    Approach 2: Add it manually in response header as below

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
       app.Use(async( context, next)=>
       {
           context.Response.Headers.Add("Access-Control-Allow-Origin","http://localhost:4200");
           context.Response.Headers.Add("Strict-Transport-Security","max-age=86400;includeSubDomains;preload");
           await next.Invoke();
       });
       app.UseMvc();
    }
  • In ASP.Net
    Add the custom header in web.config as below to implement hsts in ASP.Net and MVC
    <system.webServer >
      <httpProtocol >
        <customHeaders >
          <add name="Strict-Transport-Security" value="max-age=31536000" / >
        </customHeaders >
      </httpProtocol >
    </system.webServer >

Note: The Strict-Transport-Security header is ignored by the browser when your site is accessed using HTTP; this is because an attacker may intercept HTTP connections and inject the header or remove it. When your site is accessed over HTTPS with no certificate errors, the browser knows your site is HTTPS capable and will honor the Strict-Transport-Security header.



Benefit of Hsts policy

It helps in minimizing the man-in-the-middle-attack till some extends. See the below example scenario described on https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security#Preloading_Strict_Transport_Security

Example Scenario:

You log into a free WiFi access point at an airport and start surfing the web, visiting your online banking service to check your balance and pay a couple of bills. Unfortunately, the access point you're using is actually a hacker's laptop, and they're intercepting your original HTTP request and redirecting you to a clone of your bank's site instead of the real thing. Now your private data is exposed to the hacker.

Strict Transport Security resolves this problem; as long as you've accessed your bank's web site once using HTTPS, and the bank's web site uses Strict Transport Security, your browser will know to automatically use only HTTPS, which prevents hackers from performing this sort of man-in-the-middle attack.


Thursday, December 27, 2018

Web API : How to enable CORS in web api (.net core)?

The browsers don't allow the cross-origin-resource-sharing(CORS) for the security reasons. But nowadays almost websites use the APIs hosted on different origin. To overcome from this problem we need to do the below setting at API side to allow the CORS.
  1. Check if the package "Microsoft.AspnetCore.Cors" is installed into the web api project otherwise install it either from nuget package manager or from below command line in VS Code/ Command --

    dotnet add package Microsoft.AspnetCore.Cors

  2. Open Startup.cs file and do the below setting

    public void ConfigureServices(IServiceCollection services)
    {
       services.AddCors();
      services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
      ...
      app.UseCors(options=> options.WithOrigins("http://www.domainexample.com").AllowAnyMethod() );

      //If you are in development phase or you don't who ever is using you API then the below setting is recommended
      //app.UseCors(options=> options.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin());

      ...
    }
    In above code "http://www.domainexample.com" could be any valid domain for which it needs to enable CORS .