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

Microsoft最近(2011年12月29日)发布了一个更新,以解决.NET Framework中的几个严重安全漏洞。MS11-100引入的修复程序之一暂时缓解了涉及哈希表冲突的潜在DoS攻击。此修复似乎会破坏包含大量POST数据的页面。在我们的例子中,在具有非常大的复选框列表的页面上。为什么会出现这种情况?

一些非官方来源似乎表明,MS11-100对回发项目设置了500的限制。我找不到微软的消息来源证实这一点。我知道视图状态和其他框架特性在一定程度上抵消了这种限制。是否有任何控制此新限制的配置设置?我们可以不使用复选框,但它非常适合我们的特定情况。我们还想使用补丁,因为它可以防止其他一些讨厌的东西。

讨论500限额的非官方消息来源:

该公告修复了DoS攻击向量,提供了对 可以为单个HTTP POST提交的变量数 请求。默认限制为500,这对于正常情况应该足够了 Web应用程序,但仍然低到足以抵消攻击 由德国的安全研究人员描述。

编辑:带有限制示例的源代码(似乎是1,000,而不是500) 创建一个标准的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(字节[]字节,编码编码)+111
system.web.httpRequest.FillInformCollection()+307

63160 次浏览

尝试在web.config中添加此设置。我刚刚在.NET 4.0上使用ASP.NET MVC 2项目测试了此设置,使用此设置,您的代码不会抛出:

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

现在(在您应用安全更新之后)应该可以更改限制。


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

enter image description here

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

enter image description here

所以这种方法绝对是新的。我在Reflector中使用了拆卸选项,从代码中可以看出,它会检查appSetting:

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

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

 _maxHttpCollectionKeys = 0x3e8;

两天前,阿列克谢·古萨罗夫(Alexey Gusarov)也在推特上谈到了这一设置:

  • http://twitter.com/#!/tr_tr_mitya/status/152473667102715904.
  • http://twitter.com/#!/tr_tr_mitya/status/152475158941138944.

__,ABC__0是来自Q&;amp;与Jonathan Ness(MSRC安全开发经理)和Pete Voss(Trustworthy Computing高级响应通信经理):

问:AppSettings.MaxHttpCollectionKeys是 是否包含最大数量的表单条目?

A:是的。

对于那些仍在使用.NET1.1的人来说,这个设置不是通过web.config配置的-它是一个注册表设置(向Michielvoo致敬,因为我是通过Reflector发现的,就像他找到答案一样)。下面的示例在32位版本的Windows上将__ABC__设置为0到5000:

Windows Registry Editor Version 5.00


[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ASP.NET\1.1.4322.0]
"MaxHttpCollectionKeys"=dword:00001388

对于64位Windows版本,请设置WOW6432节点下的密钥:

Windows Registry Editor Version 5.00


[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\ASP.NET\1.1.4322.0]
"MaxHttpCollectionKeys"=dword:00001388

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。然后,我们回收应用程序池,这将在几个小时内解决问题。

我只是想在这里加上我的0.02美元,让人们看到奇怪的地方。

如果您的应用程序将页面信息存储到ASP.NET ViewState中,并且超过了Web服务器的阈值,那么您将会遇到此问题。与其直接应用Web.config修复问题,不如先看看如何优化代码。

查看源代码,并查找1000多个ViewState隐藏字段,您就有问题了。

如果您使用的是ASP.NET核心,则可以在Startup#ConfigureReservices中设置此设置

services.Configure<FormOptions>(options => options.ValueCountLimit = 1000); // you may want to adjust this limit

参考文献: 堆栈溢出