Friday, December 30, 2011

MaxHttpCollectionKeys

Update: Microsoft released a knowledge base article about this that can be found here.


Microsoft released security bulletin MS11-100 yesterday for the .Net framework.  These are critical updates, so you should apply them.  If you're running the .Net framework 4.0 you'll install KB2556351.  One of the things this update does is update the System.Web.dll.  In the new System.Web.dll they modified some of the internal classes and put a limit on the number of form input elements that can be submitted to a page.  This was most likely done to thwart against the hash DOS attack.  The default number of input html elements that can be submitted is now 1000.  

If you would like to increase this limit or if you are paranoid and want to decrease it even more, you can. 

Microsoft doesn't have any documentation on how to do it but if you dig through the IL you can figure it out.  You'll find the function ThrowIfMaxHttpCollectionKeysExceeded() on the HttpValueCollection function.  This function is called on every form submission and it checks the length of the HttpValueCollection against an internal variable call MaxHttpCollectionKeys.  If  the number of items in HttpValueCollection  is greater then MaxHttpCollectionKeys then the function ThrowIfMaxHttpCollectionKeysExceeded() does just what it sounds like it should.   It throws an exception.  The exception isn't the most intuitive though.  (See sample exception below.) 

By default MaxHttpCollectionKeys is set to 1000.  The question is how do you change this?  Not documented, but simple to do.  Add the following element to your AppSettings in your web.config:

<appSettings>
<add key="aspnet:MaxHttpCollectionKeys" value="<new value>" />
 </appSettings>

Where <new value> is the number of input elements you want to allow on form submission.  Be it a number greater then 1000 or less than 1000.

The following error is what you will see if you go over the 1000 item limit:

Server Error in '/' Application.


Operation is not valid due to the current state of the object.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.InvalidOperationException: Operation is not valid due to the current state of the object.

Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Stack Trace:

[InvalidOperationException: Operation is not valid due to the current state of the object.]
   System.Web.HttpValueCollection.ThrowIfMaxHttpCollectionKeysExceeded() +2420258
   System.Web.HttpValueCollection.FillFromEncodedBytes(Byte[] bytes, Encoding encoding) +58
   System.Web.HttpRequest.FillInFormCollection() +159

[HttpException (0x80004005): The URL-encoded form data is not valid.]
   System.Web.HttpRequest.FillInFormCollection() +217
   System.Web.HttpRequest.get_Form() +104
   System.Web.HttpRequest.get_HasForm() +9038047
   System.Web.UI.Page.GetCollectionBasedOnMethod(Boolean dontReturnNull) +97
   System.Web.UI.Page.DeterminePostBackMode() +69
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +135



Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.272


5 comments:

  1. Thanks ever so much for this. I would never have guessed this without your help

    ReplyDelete
  2. Thanks a lot, to quickly determine how many input fields I have on my page I used this little jquery snippet:

    $(":input").length

    ReplyDelete
  3. I have faced same issue and fixed with above settings. I would like to know whether would we get any new issues with this implementation? Because I have to move it to production. Please suggest asap.

    ReplyDelete