Using the ASP.NET Health Monitoring Provider to Secure Your Application in the Case of an Attack

The ASP.NET Health Monitoring is a featured introduced in ASP.NET 2.0. Basically, you have your application raise web events – not to be confused with user interface events – and you configure rules that define, for a given event code or range of event codes, a time interval and a minimum and maximum number of occurrences, the health monitoring provider that the events will be routed to. The ASP.NET infrastructure already raises a number of these events, and you can also define your own events, and take the responsibility to raise them when appropriate. I won’t go into describing how the health monitoring works, there are several web sites that describe it, instead, I will talk about a different use.

The included providers operate in a passive way, they do things such as inserting the raised event into a database, send an email with its data, write an entry to the event log, etc:

 ASP .NET Health Monitoring Provider Class Diagram  

EventLogWebEventProvider

 

Writes events to the Event Log

SimpleMailWebEventProvider

Sends simple, unformatted email

TemplatedMailWebEventProvider

Sends template-formatted email

SqlWebEventProvider

Writes events to SQL Server

IisTraceWebEventProvider

Routes events to IIS 7 logging

TraceWebEventProvider

Writes events to the trace

WmiWebEventProvider

Routes events to WMI

I want to have something different: whenever there are more than 5 failed logins in 1 minute, I assume an attack is under way, and the site is locked down. I understand this is an extreme decision, but there may be cases where this actually makes sense.

A WebAuthenticationFailureAuditEvent event is raised with event code AuditFormsAuthenticationFailure is raised when a failed authentication using Forms Authentication occurs. So, in order to fire a provider whenever there are 5 in a minute, we must add the following to the Web.config file:

   1: <healthMonitoring>
   2:     <rules>
   3:         <add name="Failed Authentication Events" eventName="Failed Authentication Events" provider="Failed Authentication Provider" minInterval="00:01:00" minInstances="5" maxLimit="*" />
   4:     </rules>
   5:     <eventMappings>
   6:         <add name="Failed Authentication Events" startEventCode="4005" endEventCode="4005" type="System.Web.Management.WebAuthenticationFailureAuditEvent, System.Web.Management" />
   7:     </eventMappings>
   8: </healthMonitoring>

As you can see, the start and end event codes are the same, we just want to fire this for the Forms Authentication login failed event.

The next thing is the implementation of the custom provider. What this will do is, when it is fired, will create a App_Offline.htm file on the root of the web site, thus effectively disabling any accesses. It’s easy to do:

   1: public class FailedAuthenticationWebEventProvider : WebEventProvider
   2: {
   3:     public override void Initialize(String name, NameValueCollection config)
   4:     {
   5:         //additional properties may be specified on the Web.config file
   6:         this.SomeAdditionalProperty = config["someAdditionalProperty"];
   7:  
   8:         config.Remove("someAdditionalProperty");
   9:  
  10:         base.Initialize(name, config);
  11:     }
  12:  
  13:     public String SomeAdditionalProperty
  14:     {
  15:         get;
  16:         set;
  17:     }
  18:  
  19:     public override void Flush()
  20:     {
  21:     }
  22:  
  23:     public override void ProcessEvent(WebBaseEvent raisedEvent)
  24:     {
  25:         //copy an existing template file to App_Offline.htm
  26:         String file = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "App_Offline.htm.bak");
  27:         File.Copy(file, Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "App_Offline.htm"));
  28:     }
  29:  
  30:     public override void Shutdown()
  31:     {       
  32:     }
  33: }

I included an additional property just for demonstrative purposes, it is not being used.

The final step is to register the new provider:

   1: <healthMonitoring>
   2:     <providers>
   3:         <add name="Failed Authentication Provider" type="FailedAuthenticationWebEventProvider" someAdditionalProperty="someValue" />
   4:     </providers>
   5:     ...
   6: </healthMonitoring>

And that’s it!

                             

4 Comments

Add a Comment

As it will appear on the website

Not displayed

Your website