首页 文章

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

提问于
浏览
196

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

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

Unofficial source discussing the 500 limit:

该公告通过限制可以为单个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 回答

  • 275

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

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

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


    我没有't updated my machine yet, so using Reflector I checked the HttpValueCollection class, and it didn'有 ThrowIfMaxHttpCollectionKeysExceeded 方法:

    enter image description here

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

    enter image description here

    所以这种方法绝对是新的 . 我在Reflector中使用了Disassemble选项,从代码中我可以看出它检查AppSetting:

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

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

    _maxHttpCollectionKeys = 0x3e8;
    

    另外,Alexey Gusarov两天前发布了关于此设置的推文:

    here是与Jonathan Ness(安全开发经理,MSRC)和Pete Voss(高级响应通信经理,可信赖计算)的问答的正式答案:

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

  • 3

    对于那些仍在使用.NET 1.1的人来说,这个设置不是通过web.config配置的 - 它是一个注册表设置(对于michielvoo,我只是通过Reflector发现这个,就像他找到答案一样) . 以下示例在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
    
  • 18

    我只想在这里加上我的0.02美元,让人们看到这种古怪 .

    如果您的应用程序将页面信息存入ASP.NET ViewState并超过Web服务器阈值,那么您将遇到此问题 . 而不是立即应用web.config修复问题,您可能希望首先考虑优化代码 .

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

  • 4

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

相关问题