Welcome to EMC Consulting Blogs Sign in | Join | Help

Howard van Rooijen's EMC Consulting Blog (2004 - 2010)

This blog has now moved to http://howard.vanrooijen.co.uk/blog - please update your subscriptions if you wish to receive new content.

Cloaking your ASP.NET MVC Web Application on IIS 7

If you are building and deploying public facing web applications, security has to be one of your key consideration; ensure that you create a security threat model of your application to highlight the flow of data in your application and the possible weak points (Microsoft have a useful tool called Microsoft Security Assessment Tool which can help you with the planning process); ensure that your production environment has been hardened (and that you have run the various tool provided to spot any vulnerabilities in your infrastructure, such as Microsoft Baseline Security Analyzer and tools like CAT.NET and Paros for spotting vulnerabilities in your application code); ensure that your web application protects against Cross Site Scripting (XSS) and Cross-Site Request Forgery (CSRF/XSRF) attacks.

If you can afford the cost, adding an Intrusion Prevention System device to your network adds benefit, but if you can’t afford such a device then a tool such as UrlScan can offer some protection by blocking potentially harmful HTTP Requests. In order to use URLScan effectively you need to put an operational feedback loop in place whereby you use a tool such as LogParser (if you want a nice UI for this command line app, give Visual LogParser a try) to examine your application’s IIS Logs for suspicious activity and add rules to UrlScan and your firewall to block such requests.

Examining IIS Server logs from a high traffic public website or having a network monitoring solution such as Cacti is fascinating and terrifying in equal measures; once you have removed the noise of normal human generated traffic, the sheer volume of remaining non-human traffic generated by bots and spiders is staggering. Once you’ve filtered out all the requests generated by search engine’s crawlers there are a surprising number of other requests being made against your servers the two worst being harvesters (screen scrapers) and bots that perform vulnerability scanning and exploitation. These bots start by fingerprinting your server and then exploit any known vulnerabilities, the HTTP RFC 2068 highlights this possibility:

"Note: Revealing the specific software version of the server may allow the server machine to become more vulnerable to attacks against software that is known to contain security holes. Server implementers are encouraged to make this field a configurable option."

There are two recourses to this situation, firstly you can broadcast a fake web topology, for example if your web platform is WISA (Windows, Internet Information Services, SQL Server, ASP.NET) you can configure your servers to return the response headers of a LAMP (Linux, Apache, MySQL, PHP) platform. Secondly you can cloak this information, so it isn’t broadcasted at all.

By default a WISA platform (running ASP.NET MVC) discloses its identity, by broadcasting the following response header (using Firebug):

image

You can turn off the X-AspNet-Version header by applying the following configuration section to your web.config:

<system.web>
  <
httpRuntime enableVersionHeader="false"/>
</
system.web>

which results in the X-AspNet-Version being removed:

image

You can then remove the X-AspNetMvc-Version header by altering your Global.asax.cs as follows:

protected void Application_Start()
{
    MvcHandler.DisableMvcResponseHeader = true;
}

which results in the X-AspNetMvc-Version being removed:

image

But there is no easy way to remove the Server response header via configuration. Luckily IIS7 has a managed pluggable module infrastructure which allows you to easily extend its functionality. Below is the source for a HttpModule for removing a specified list of HTTP Response Headers:

namespace Zen.Core.Web.CloakIIS
{
#region Using Directives

using System;
using System.Collections.Generic;
using System.Web;

#endregion

/// <summary>
///
Custom HTTP Module for Cloaking IIS7 Server Settings to allow anonymity
/// </summary>
public class CloakHttpHeaderModule : IHttpModule
{
/// <summary>
///
List of Headers to remove
/// </summary>
private List<string> headersToCloak;

/// <summary>
///
Initializes a new instance of the <see cref="CloakHttpHeaderModule"/> class.
/// </summary>
public CloakHttpHeaderModule()
{
this.headersToCloak = new List<string>
{
"Server",
"X-AspNet-Version",
"X-AspNetMvc-Version",
"X-Powered-By",
};
}

/// <summary>
///
Dispose the Custom HttpModule.
/// </summary>
public void Dispose()
{
}

/// <summary>
///
Handles the current request.
/// </summary>
/// <param name="context">
///
The HttpApplication context.
/// </param>
public void Init(HttpApplication context)
{
context.PreSendRequestHeaders += this.OnPreSendRequestHeaders;
}

/// <summary>
///
Remove all headers from the HTTP Response.
/// </summary>
/// <param name="sender">
///
The object raising the event
/// </param>
/// <param name="e">
///
The event data.
/// </param>
private void OnPreSendRequestHeaders(object sender, EventArgs e)
{
this.headersToCloak.ForEach(h => HttpContext.Current.Response.Headers.Remove(h));
}
}
}

Ensure that you sign the assembly, then you can install it into the GAC of your web servers and simply make the following modification to your application’s web.config (or if you want it to be globally applied, to the machine.config):

<configuration>
<
system.webServer>
<
modules>
<
add name="CloakHttpHeaderModule"
type="Zen.Core.Web.CloakIIS.CloakHttpHeaderModule, Zen.Core.Web.CloakIIS,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=<YOUR TOKEN HERE>
" />
</
modules>
</
system.webServer>
</
configuration>

Now when you execute a page, you should see the following HTTP Response (with X-AspNetMvc-Version, X-AspNetMvc-Version and Server response headers removed):

image

One further note – the bots also fingerprint via file extensions, if you are running ASP.NET MVC, extensionless URLs implemented via the ASP.NET MVC routing system, should help avoid this type of detection.

@HowardvRooijen

Published Tuesday, August 25, 2009 11:48 AM by howard.vanrooijen

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

 

Mark.Mann said:

nice post howard!

i thought i had done most of the rudimentary config changes to my live servers (eg: disable ping, skeletal error pages for 404/500, minmal host headers etc...) but in the current world of websites and web services it looks like there are few other tricks to implement!

sniffing and spiders are much more sophisticated nowadays i'll have to break open some of the latest vunrability checking tools too!

August 25, 2009 7:22 PM
 

howard.vanrooijen said:

Thanks Mark.

You should talk to Justin Short as he's really the expert on the team and he did all of our threat modelling. Also really worth watching the Scott Hanselman and Phil Haack presentation at NDC 2009 - Phil builds a web app then Scott hacks it - very interesting (and scary) indeed.

August 26, 2009 9:56 AM
 

Andrea Moro said:

Great post, but don't really understand why you felt the necessity to remove the headers. They are important.

Can you point me out on your necessity? May be I so oaken to don't see it.

November 25, 2009 8:44 PM
 

dan said:

tipical Microsoftee... hide the server header hoping that the script kiddies won't know which server is..

March 15, 2010 6:23 PM
 

howard.vanrooijen said:

@dan yes, isn't it a terrible and lazy mistake to try every trick in the book to stop automated attacks against your services.

March 15, 2010 7:44 PM

Leave a Comment

(required) 
(optional)
(required) 
Submit

This Blog

Syndication

News

This blog has now moved - please visit http://howard.vanrooijen.co.uk/blog for new content!
Add to Live.com
Powered by Community Server (Personal Edition), by Telligent Systems