Security: HTTP headers that expose web application / server vulnerabilities

Today's blog post will cover how ASP.net response HTTP headers can expose security holes in your web application and servers. The post will also contain steps on how to remove this headers and mitigate chances of getting attacked using C# and ASP.net MVC.

Problem

When an attacker performs an attack on a web server, the first thing he /she needs to do is to identify the profile of his target. To profile a target web application / server, an attacker would have to perform the following steps:

  • Identify the address of the web application.
  • Identify the OS where the web application resides
  • Identify the type of server (IIS, Apache, etc) that was hosting the web application
  • Identify the frameworks (ASP.net MVC, PHP, JSF) used by the applications

After an attacker gathers the following information, the attacker would proceed on using penetration tools (Kali's Metasploit and Websploit) to perform different kinds of attacks to disrupt the target which could mean:

  • Defacing the application
  • Performing denial of service attacks
  • Disabling of web server itself
  • Kidnapping of database server for ransom

ASP.NET MVC Solution Github

One way to delay an attacker from executing an attack on your server is to remove HTTP headers that identify IIS and ASP.net powered applications. Below are the list of HTTP headers that needs to be removed from your applications response headers:

  • Server
  • X-AspNetMvc-Version
  • X-AspNet-Version
  • X-Powered-By

These HTTP headers can be removed by configuring an IIS server manually. This approach is OK but infeasible because the most common cause of an attack to a web server is scaling (Adding of servers / load balancers in a web farm) without configuring the additional machine. Sometimes, IT people in-charge of configuring newly added server nodes forget to disable the inclusion of these headers to the application's response objects. To make things worst, newbies are clueless with the existence of these headers. As responsible developers, we find this annoying and simply unacceptable.

To prevent hackers from retrieving HTTP server information headers, we can implement a class that would strip all these headers from all the responses emitted by an ASP.net application. The class below does the trick:

Clone it from Github

using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace ServerIdentityHttpHeaderStripping
{
    /// <summary>
    /// Class that implements methods used for
    /// stripping out HTTP response headers.
    /// </summary>
    public class ServerIdentityStripper
    {
        #region Public Methods
        /// <summary>
        /// Method that strips out HTTP response headers 
        /// from response.
        /// execution.
        /// </summary>
        /// <param name="context">
        ///     Http context associated with the response 
        ///     that would be stripped of server identity 
        ///     headers.
        /// </param>
        public void Execute(HttpContext context)
        {
            var serverHeaders = GetServerIdentityHeaders();
            StripServerHeaders(context.Response, serverHeaders);
        }
        #endregion
        #region Private Methods
        private bool CheckIfHttpHeaderExists(HttpResponse response, string header)
        {
            return response.Headers
                           .AllKeys
                           .Any(k => k == header);
        }
        private List<string> GetServerIdentityHeaders()
        {
            return new List<string>
            {
                "Server",
                "X-AspNetMvc-Version",
                "X-AspNet-Version"
            };
        }
        private void StripServerHeaders(HttpResponse response, List<string> headers)
        {
            foreach (var header in headers)
            {
                if (CheckIfHttpHeaderExists(response, header))
                    response.Headers.Remove(header);
            }
        }
        #endregion
    }
}

You also have to add the following code on Global.Asax's Application_EndRequest event.

        protected void Application_EndRequest()
        {
            var stripper = new ServerIdentityStripper();

            stripper.Execute(HttpContext.Current);
        }

X-Powered-By

Unfortunately, the class can strip all necessary headers except for the "X-Powered-By" header. This happens because IIS is the one that attaches this HTTP header after the application release the response object. To ensure that this HTTP header would be removed from your server's response headers. You can add the configuration below on your application's web.config file.

   <system.webServer>
    <httpProtocol>
    <customHeaders>
    <remove name="X-Powered-By" />
      </customHeaders>
    </httpProtocol>
  </system.webServer>

Result

Comments

Popular posts from this blog

Building Simple API Gateways with Ocelot and ASP.net Core

API Gateway in a Nutshell

Replicating Netflix Part 1: Installing Raspbian Lite using Etcher

10 Steps to Setup and Containerize an Express Server