Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I've written this module (using a tutorial on the web I can't find now to stop unusual requests from clients. It's working as I've tested it on a local system.

  1. Is the logic fine enough?

  2. Another problem is that it counts requests for non-aspx resources (images, css, ...), but it shouldn't. How can I filter request for aspx pages ?

This is the module code:

public class AntiDosModule : IHttpModule
{
    const string blockKey = "IsBlocked";
    const string reqsKey = "Requests";


    public void Dispose()
    { }

    public void Init(HttpApplication context)
    {
        context.BeginRequest += ValidateRequest;
    }

    private static void ValidateRequest(object sender, EventArgs e)
    {
        // get configs from web.config
        AntiDosModuleSettings setting = AntiDosModuleSettings.GetConfig();

        int blockDuration = setting.IPBlockDuration;

        // time window in which request are counted e.g 1000 request in 1 minute
        int validationTimeWindow = setting.ValidationTimeWindow;

        // max requests count in specified time window e.g 1000 request in 1 minute
        int maxValidRequests = setting.MaxValidRequests;

        string masterKey = setting.MasterKey;

        HttpContextBase context = new HttpContextWrapper(HttpContext.Current);

        CacheManager cacheMgr = new CacheManager(context, masterKey);

        // is client IP blocked
        bool IsBlocked = (bool)cacheMgr.GetItem<Boolean>(blockKey);

        if (IsBlocked)
        {
            context.Response.End();
        }


        // number of requests sent by client till now
        IPReqsHint hint = cacheMgr.GetItem<IPReqsHint>(reqsKey) ?? new IPReqsHint();

        if (hint.HintCount > maxValidRequests)
        {
            // block client IP
            cacheMgr.AddItem(blockKey, true, blockDuration);

            context.Response.End();

        }


        hint.HintCount++;

        if (hint.HintCount == 1)
        {
            cacheMgr.AddItem(reqsKey, hint, validationTimeWindow);
        }

    }

}

internal class IPReqsHint
{

    public int HintCount { get; set; }

    public IPReqsHint()
    {
        HintCount = 0;
    }
}

and this is the CacheManager class:

public class CacheManager
{

    HttpContextBase context;

    string masterKey;

    public CacheManager(HttpContextBase context, string masterKey)
    {
        this.context = context;
        this.masterKey = masterKey;
    }

    public void AddItem(string key, object value, int duration)
    {
        string finalKey = GenerateFinalKey(key);

        context.Cache.Add(
            finalKey,
            value,
            null,
            DateTime.Now.AddSeconds(duration),
            System.Web.Caching.Cache.NoSlidingExpiration,
            System.Web.Caching.CacheItemPriority.Normal,
            null);
    }

    public T GetItem<T>(string key)
    {
        string finalKey = GenerateFinalKey(key);

        var obj = context.Cache[finalKey] ?? default(T);

        return (T)obj;
    }

    string GenerateFinalKey(string key)
    {
        return masterKey + "-" + context.Request.UserHostAddress + "-" + key;
    }
}
share|improve this question
add comment

1 Answer

There definitely are not enough of these tools in the .NET world, but I've found that there are a lot in the WordPress/php world. My recommendation would be to review the code in those modules to determine if the logic is good enough. Certainly, "good enough" depends on your needs though.

Regarding the filtering of specific file types, perhaps http://stackoverflow.com/questions/331398/how-to-have-http-module-on-fire-events-only-for-specific-page-types will help?

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.