Wednesday, October 31, 2012

Block DoS attacks easily in ASP.NET

DoS Attack started with a warning message like this :


Today i have facing a problem of the Denial of Service (DoS) attacks on my public facing anonymous web site.

My server return the error message as "Server is too busy, Try again later".

We have firewall as well, But we dont block the IP's coz its dynamic all over the world.

Please guide me how we can prevent this attack. Or is there any way to avoid this kind of attack from the sharepoint or from the code

for this problem Mads Kristensen have simple solution  :


Denial of Service (DoS) attacks are becoming a more and more common way to bring websites and servers down. They are very easy to do and pretty hard to protect against, which is why they are so popular. The only thing you can do to prevent such an attack is to block the response to the attackers. You have no control over the requests, so you have to catch the attacker as early as possible after the request has been received by the web server.
There are two challenges to blocking the attacks
  • Identify the attackers
  • Block the response only to the attackers
To catch the request as early as possible, an HttpModule is the right place. It is executed before any page or any other handler so the impact on the server can be minimized. This HttpModule monitors all requests and block requests coming from IP addresses that make many requests in a short period of time. After a while the attacking IP address gets released from blocking.
The module is a high performance and lightweight protection from DoS attacks and very easy to implement.

Implementation


Download the DosAttackModule.cs file below and put it into the App_Code folder of your website. Then add the following lines to the web.config’s <system.web> section:
< httpModules >
< add type = " DosAttackModule " name = " DosAttackModule " />
</ httpModules >

Download



#region Using

using System;
using System.Web;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Timers;

#endregion

/// <summary>
/// Block the response to attacking IP addresses.
/// </summary>
public class DosAttackModule : IHttpModule
{

  #region IHttpModule Members

  void IHttpModule.Dispose()
  {
    // Nothing to dispose; 
  }

  void IHttpModule.Init(HttpApplication context)
  {
    context.BeginRequest += new EventHandler(context_BeginRequest);
  }

  #endregion

  #region Private fields

  private static Dictionary<string, short> _IpAdresses = new Dictionary<string, short>();
  private static Stack<string> _Banned = new Stack<string>();
  private static Timer _Timer = CreateTimer();
  private static Timer _BannedTimer = CreateBanningTimer();

  #endregion

  private const int BANNED_REQUESTS = 10;
  private const int REDUCTION_INTERVAL = 1000; // 1 second
  private const int RELEASE_INTERVAL = 5 * 60 * 1000; // 5 minutes

  private void context_BeginRequest(object sender, EventArgs e)
  {
    string ip = HttpContext.Current.Request.UserHostAddress;
    if (_Banned.Contains(ip))
    {
      HttpContext.Current.Response.StatusCode = 403;
      HttpContext.Current.Response.End();
    }

    CheckIpAddress(ip);
  }

  /// <summary>
  /// Checks the requesting IP address in the collection
  /// and bannes the IP if required.
  /// </summary>
  private static void CheckIpAddress(string ip)
  {
    if (!_IpAdresses.ContainsKey(ip))
    {
      _IpAdresses[ip] = 1;
    }
    else if (_IpAdresses[ip] == BANNED_REQUESTS)
    {
      _Banned.Push(ip);
      _IpAdresses.Remove(ip);
    }
    else
    {
      _IpAdresses[ip]++;
    }
  }

  #region Timers

  /// <summary>
  /// Creates the timer that substract a request
  /// from the _IpAddress dictionary.
  /// </summary>
  private static Timer CreateTimer()
  {
    Timer timer = GetTimer(REDUCTION_INTERVAL);
    timer.Elapsed += new ElapsedEventHandler(TimerElapsed);
    return timer;
  }

  /// <summary>
  /// Creates the timer that removes 1 banned IP address
  /// everytime the timer is elapsed.
  /// </summary>
  /// <returns></returns>
  private static Timer CreateBanningTimer()
  {
    Timer timer = GetTimer(RELEASE_INTERVAL);
    timer.Elapsed += delegate { _Banned.Pop(); };
    return timer;
  }

  /// <summary>
  /// Creates a simple timer instance and starts it.
  /// </summary>
  /// <param name="interval">The interval in milliseconds.</param>
  private static Timer GetTimer(int interval)
  {
    Timer timer = new Timer();
    timer.Interval = interval;
    timer.Start();

    return timer;
  }

  /// <summary>
  /// Substracts a request from each IP address in the collection.
  /// </summary>
  private static void TimerElapsed(object sender, ElapsedEventArgs e)
  {
    foreach (string key in _IpAdresses.Keys)
    {
      _IpAdresses[key]--;
      if (_IpAdresses[key] == 0)
        _IpAdresses.Remove(key);
    }
  }

  #endregion

}

for better view you can also view this article 
http://blog.ehuna.org/2012/04/how_to_stop_a_denial_of_servic.html from EHUNA.ORG



No comments:

Post a Comment