ASP.NET MS11-100:如何更改发布表单值的最大数量限制?

微软最近(12-29-2011)发布了一个更新来解决.NET Framework中的几个严重的安全漏洞。 MS11-100引入的修复之一暂时减轻了涉及散列表冲突的潜在DoS攻击。 看来这个修补程序会中断包含大量POST数据的页面。 在我们的例子中,在具有非常大的checkbox列表的页面上。 为什么会这样呢?

一些非官方消息来源似乎表明,MS11-100对回发项目的限制是500。 我无法find确认这一点的微软源代码。 我知道,视图状态和其他框架function吃了一些这个限制。 是否有任何configuration设置来控制这个新的限制? 我们可以切换使用checkbox,但它对我们的特定情况非常有效。 我们也想要应用这个补丁,因为它可以防止其他一些讨厌的东西。

讨论500限制的非官方来源:

该公告修复了DOS攻击vector,通过提供一个HTTP POST请求可以提交的variables数量的限制。 默认限制是500,对于正常的Web应用程序来说应该足够了,但是仍然足够低以抵消德国安全研究人员所描述的攻击。

编辑:源代码与限制(似乎是1,000,而不是500)的示例创build一个标准的MVC应用程序,并将下面的代码添加到主索引视图:

@using (Html.BeginForm()) { <fieldset class="fields"> <p class="submit"> <input type="submit" value="Submit" /> </p> @for (var i = 0; i < 1000; i++) { <div> @Html.CheckBox("cb" + i.ToString(), true) </div> } </fieldset> } 

此代码在补丁之前工作。 它以后不工作。 错误是:

[InvalidOperationException:由于对象的当前状态,操作无效。]
System.Web.HttpValueCollection.ThrowIfMaxHttpCollectionKeysExceeded()+82 System.Web.HttpValueCollection.FillFromEncodedBytes(Byte [] bytes,Encoding encoding)+111
System.Web.HttpRequest.FillInFormCollection()+307

尝试在web.config中添加此设置。 我只是用ASP.NET MVC 2项目在.NET 4.0上testing了这个,并且这个设置代码不会抛出:

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

这应该(现在应用安全更新后)更改限制。


我还没有更新我的机器,所以使用Reflector我检查了HttpValueCollection类,它没有ThrowIfMaxHttpCollectionKeysExceeded方法:

在这里输入图像描述

我安装了KB2656351 (.NET 4.0的更新),重新加载了Reflector中的程序集,并且出现了这个方法:

在这里输入图像描述

所以这个方法肯定是新的。 我在Reflector中使用了Disassemble选项,从代码中可以看出它检查了一个AppSetting:

 if (this.Count >= AppSettings.MaxHttpCollectionKeys) { throw new InvalidOperationException(); } 

如果在web.config文件中找不到值,则在System.Web.Util.AppSettings.EnsureSettingsLoaded (内部静态类)中将其设置为1000:

  _maxHttpCollectionKeys = 0x3e8; 

此外,阿列克谢·古萨罗夫(Alexey Gusarov)在两天前发布了关于这个设置的推文:

Jonathan Ness(MSRC安全发展经理)和Pete Voss(可信赖计算高级响应通信经理)的Q&A官方答复如下:

问:AppSettings.MaxHttpCollectionKeys是包含最大表单条目数的新参数吗?

答:是的。

对于那些仍在使用.NET 1.1的人来说,这个设置不是通过web.config来configuration的 – 这是一个registry设置(通过Reflector,我发现了这个问题,就像他find答案一样)。 下面的示例将32位版本的Windows上的MaxHttpCollectionKeys设置为5000:

 Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ASP.NET\1.1.4322.0] "MaxHttpCollectionKeys"=dword:00001388 

对于64位Windows版本,请在Wow6432Node下设置密钥:

 Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\ASP.NET\1.1.4322.0] "MaxHttpCollectionKeys"=dword:00001388 

我只想在这里为我看到这个奇怪的人添加0.02美元。

如果您的应用程序将页面信息存储到ASP.NET ViewState中,并且超过了Web服务器的阈值,那么您将遇到这个问题。 不要马上应用web.config修复问题,你可能想先看看优化你的代码。

查看源代码,并查找1000多个视图状态的隐藏字段,你有你的问题。

ThrowIfMaxHttpCollectionKeysExceeded()也被添加到System.Web.HttpCookieCollection

它看起来像HttpCookieCollection.Get()被调用时,它在内部调用HttpCookieCollection.AddCookie() ,然后调用ThrowIfMaxHttpCollectionKeysExceeded()

 public HttpCookie Get(string name) { HttpCookie cookie = (HttpCookie) base.BaseGet(name); if ((cookie == null) && (this._response != null)) { cookie = new HttpCookie(name); this.AddCookie(cookie, true); this._response.OnCookieAdd(cookie); } return cookie; } internal void AddCookie(HttpCookie cookie, bool append) { this.ThrowIfMaxHttpCollectionKeysExceeded(); this._all = null; this._allKeys = null; if (append) { cookie.Added = true; base.BaseAdd(cookie.Name, cookie); } else { if (base.BaseGet(cookie.Name) != null) { cookie.Changed = true; } base.BaseSet(cookie.Name, cookie); } } 

我们所看到的是,在几个小时内,网站变得越来越慢,越来越慢,直到开始抛出InvalidOperationExcpetion 。 然后,我们回收应用程序池,将问题修复了几个小时。