Daily Archives: August 7, 2013

Mitigating DoS attacks in ASP.NET

According to a widely accepted view, there is no effective countermeasure against (Distributed) Denial of Service attacks. End of story.

That’s kinda true, especially if the attack is based on sending numerous small requests to the webserver. However, websites can also be DoS’ed by sending huge HTTP requests, which can cause memory issues on the server. Actually the same can happen when non-malicious users upload files that are much bigger than expected.

You can mitigate this threat by setting the maximum accepted size for a HTTP request. It is important to understand that implementing such checking in an ASP.NET event handler is far too late, because when that handler is called, the request is already arrived to the server. Thankfully both ASP.NET and IIS provides endpoints in the earlier phases of the request pipeline.

ASP.NET provides the maxRequestLength attribute which you can configure in web.config. The default value is 4096 and that means 4096 kilobytes:

<httpRuntime targetFramework="4.5" maxRequestLength="4096"/>

So by default ASP.NET aborts all requests which are larger than 4MB with a HttpException:

HttpException (0x80004005): Maximum request length exceeded.

Unfortunately this exception is far too general, you cannot use any of its properties (beside the localized error message) to identify this special issue, but this workaround works well:

void Application_Error( object sender, EventArgs e )
  HttpRuntimeSection section = ConfigurationManager.GetSection( 
"system.web/httpRuntime" ) as
HttpRuntimeSection; int maxRequestLength = section.MaxRequestLength; if( this.Request.ContentLength > maxRequestLength * 1024 ) { this.Server.ClearError(); // Log and redirect to a friendly error page etc. } }

IIS provides the Request Filtering module which (beside many other useful features) also allows you to set the maximum allowed request length in the maxAllowedContentLength attribute. The default is 30000000 here and it means about 28.6MB, because it is measured in bytes:

      <requestLimits maxAllowedContentLength="30000000" />

When this limit is reached, IIS issues a response with HTTP Error 404.13:


You can handle this error as well in global.asx, but this time you need to implement the Application_EndRequest event handler:

protected void Application_EndRequest( object sender, EventArgs e )
  if( this.Response.StatusCode == 404 && this.Response.SubStatusCode == 13 )
    // Log, redirect, etc.


Technorati-címkék: ,,,,,