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


196

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

一些非官方消息来源似乎表明,MS11-100对回发项目的限制是500。我找不到可以证实这一点的Microsoft资源。我知道View State和其他框架功能会吃掉这个限制。是否有任何控制此新限制的配置设置?我们可以放弃使用复选框,但是在我们的特定情况下效果很好。我们还想应用补丁,因为它可以防止其他令人讨厌的事情。

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

该公告通过限制可以为单个HTTP POST请求提交的变量数量来修复DOS攻击向量。默认限制为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(Byte []个字节,编码编码)+111
System.Web。 HttpRequest.FillInFormCollection()+307


怎么样做一些额外的立法工作,并在该节中专门说明500。–
OO

3
就是这样 没有节(来自Microsoft)。只是来自非正式的评论员,他们可能知道也可能不知道他们在说什么。我仍然发布了链接和摘要。
colithium 2011年

1
@Andrew:我能想到的唯一的“多重选择列表”是将SelectionMode设置为Multiple的ListBox。实际上,这可能会发布多个值。但是,问题提到“下拉列表”。然后,让我们等待问题作者的任何评论。
Wiktor Zychla 2011年

1
有关此主题的最新问题确定该修补程序通过限制帖子数来缓解DOS。
约翰·桑德斯

1
有关详细信息,请参阅support.microsoft.com/kb/2661403

Answers:


275

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

<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文件中找不到该值,则会将其设置为1000 in System.Web.Util.AppSettings.EnsureSettingsLoaded(内部静态类):

 _maxHttpCollectionKeys = 0x3e8;

另外,两天前,Alexey Gusarov在推特上发布了此设置:

这里是从Q&A与乔纳森·内斯(安全开发经理,MSRC)和皮特·沃斯(高级响应通信经理,可信赖计算)的官方的回答:

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

答:是的。


25
精彩。这些是让我喜欢stackoverflow的答案
colithium 2011年

4
它确实有帮助,我希望我有另一个帐户,以便我可以给+2 :)
misha 2012年

1
可以在整个服务器的applicationhost.config中更新它吗?或machine.config?
andryuha 2012年

1
有什么办法可以在每页级别上控制此限制?(也在这里这里问。)
Mike Guthrie 2012年

1
有些人建议您检查网页,因为它不应该包含这么多的表单字段。但是,对于此错误,我们有一个非常有效的方案-我们客户的一个电子商务网站中的购物车中有很多物品,当她访问该页面时,我们记录了此错误。在这种情况下,覆盖最大值是最佳选择。
Ankur-m

18

对于仍在使用.NET 1.1的用户,此设置未通过web.config进行配置-这是一个注册表设置(michielvoo的技巧提示,因为我只是通过Reflector发现它的方式与他找到答案的方式相同)。下面的示例在MaxHttpCollectionKeysWindows 32位版本上设置为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

关于该安全修复程序可以缓解的DoS攻击,您是否了解5000的合理安全值?我们正在考虑使用相同的5000值,但我找不到有关攻击次数中每个请求所消耗的值数与CPU时间之间的关系的任何信息……
Tao

4

我只想在这里添加0.02美元,以供看到奇怪的人们使用。

如果您的应用程序将页面信息隐藏到ASP.NET ViewState中,并且超过了Web服务器的阈值,那么您将遇到此问题。与其立即解决web.config修复问题,不如先考虑优化代码。

查看源代码,然后查找1000多个viewstate隐藏字段,您就遇到了问题。


1000多个viewstate字段?表单上是否只有一个ViewState字段。该值是随表单字段数量增加而增加的值。
Ankur-m 2013年

3

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。然后,我们回收应用程序池,从而将问题修复了几个小时。


cookie数限制是一个不错的选择。对于您描述的速度缓慢和错误,您是否知道它实际上与请求中的Cookie计数有关?您检查客户要求了吗?(您的应用是否故意使用大量Cookie进行操作?)
2012年

1
事实证明,我们有一个自定义CookieProvider,它在应用启动时错误地获取了对Request.Cookies集合的单例引用,然后在每个后续请求中,它将检查静态cookie集合中是否存在一个或多个cookie。 ...从上面的代码中可以看到,.Net ADDS默认情况下未找到该cookie。因此,随着时间的推移,随着每个用户访问系统,各种cookie被添加到该单例集合中……并且由于该站点被设计为可以使用cookie,也可以不使用cookie,因此从未发现此错误(直到现在)
Joshua Barker
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.