196

Microsoft 最近 (12-29-2011) 发布了一个更新,以解决 .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[] bytes, Encoding encoding) +111
System.Web。 HttpRequest.FillInFormCollection() +307

4

5 回答 5

277

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

 _maxHttpCollectionKeys = 0x3e8;

此外,Alexey Gusarov 两天前在推特上发布了有关此设置的信息:

以下是 Jonathan Ness(安全开发经理,MSRC)和 Pete Voss(高级响应通信经理,可信赖计算)的官方回答:

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

答:是的。

于 2011-12-30T22:58:29.643 回答
18

对于那些仍在使用 .NET 1.1 的人,此设置不是通过 web.config 配置的——它是一个注册表设置(向 michielvoo 致敬,因为我只是通过 Reflector 发现了这一点,就像他找到了答案一样)。以下示例MaxHttpCollectionKeys在 32 位版本的 Windows 上设置为 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
于 2012-01-03T19:47:50.533 回答
4

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

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

查看源代码,并查找 1000 多个视图状态隐藏字段,您就遇到了问题。

于 2012-01-10T19:01:36.410 回答
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);
    }
}

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

于 2012-01-06T17:40:56.620 回答
1

如果您使用的是 ASP.NET CORE,您可以在 Startup#ConfigureServices 中设置此设置

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

参考: 堆栈溢出

于 2020-12-15T20:10:59.357 回答