ASP.NET MS11-100: ¿cómo puedo cambiar el límite en el número máximo de valores de formulario publicados?
post (4)
Intente agregar esta configuración en web.config. Acabo de probar esto en .NET 4.0 con un proyecto ASP.NET MVC 2 y con esta configuración, su código no arroja:
<appSettings>
<add key="aspnet:MaxHttpCollectionKeys" value="1001" />
</appSettings>
Eso debería funcionar ahora (después de haber aplicado la actualización de seguridad) para cambiar el límite.
No había actualizado mi máquina todavía, por lo que al usar Reflector revisé la clase HttpValueCollection y no tenía el método ThrowIfMaxHttpCollectionKeysExceeded
:
Instalé MS11-100 (actualización para .NET 4.0), recargué los ensamblajes en Reflector y apareció el método:
Así que ese método es definitivamente nuevo. Utilicé la opción Desensamblar en Reflector, y por lo que puedo decir del código, verifica un ajuste de aplicación:
if (this.Count >= AppSettings.MaxHttpCollectionKeys)
{
throw new InvalidOperationException();
}
Si no encuentra el valor en el archivo web.config, lo establecerá en 1000 en System.Web.Util.AppSettings.EnsureSettingsLoaded
(una clase estática interna):
_maxHttpCollectionKeys = 0x3e8;
Además, Alexey Gusarov tuiteó sobre esta situación hace dos días:
- http://twitter.com/#!/tr_tr_mitya/status/152473667102715904
- http://twitter.com/#!/tr_tr_mitya/status/152475158941138944
Y here hay una respuesta oficial de una sesión de preguntas y respuestas con Jonathan Ness (Gerente de Desarrollo de Seguridad, MSRC) y Pete Voss (Gerente de Comunicaciones de Respuesta de Sr., Computación Confiable):
P: ¿Es AppSettings.MaxHttpCollectionKeys el nuevo parámetro que contiene el número máximo de entradas de formulario?
A: sí lo es.
Microsoft recientemente (12-29-2011) lanzó una actualización para abordar varias vulnerabilidades de seguridad graves en .NET Framework. Una de las correcciones introducidas por MS11-100 mitiga temporalmente un posible ataque DoS que involucra colisiones de tablas hash. Parece que esta corrección rompe las páginas que contienen una gran cantidad de datos POST. En nuestro caso, en páginas que tienen listas de casillas muy grandes. Por qué sería este el caso?
Algunas fuentes no oficiales parecen indicar que MS11-100 coloca un límite de 500 en los elementos de devolución de datos. No puedo encontrar una fuente de Microsoft que confirme esto. Sé que View State y otras características del marco comen algo de este límite. ¿Hay algún ajuste de configuración que controle este nuevo límite? Podríamos dejar de usar casillas de verificación, pero funciona bastante bien para nuestra situación particular. También nos gustaría aplicar el parche porque protege contra algunas otras cosas desagradables.
Fuente no oficial que discute el límite de 500:
El boletín corrige el vector de ataque de DOS al proporcionar un límite al número de variables que se pueden enviar para una única solicitud HTTP POST. El límite predeterminado es 500, que debería ser suficiente para las aplicaciones web normales, pero aún lo suficientemente bajo como para neutralizar el ataque como lo describen los investigadores de seguridad en Alemania.
EDITAR: Código fuente con ejemplo de límite (que parece ser 1,000, no 500) Cree una aplicación MVC estándar y agregue el siguiente código a la vista del índice principal:
@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>
}
Este código funcionó antes del parche. No funciona después. El error es:
[InvalidOperationException: la operación no es válida debido al estado actual del objeto.]
System.Web.HttpValueCollection.ThrowIfMaxHttpCollectionKeysExceeded () +82 System.Web.HttpValueCollection.FillFromEncodedBytes (Byte [] bytes, codificación de codificación) +111
System.Web.HttpRequest.FillInFormCollection () +307
Para aquellos de ustedes que todavía usan .NET 1.1, esta configuración no se configura a través de web.config, es una configuración de registro (sugerencia a michielvoo, ya que solo descubrí esto a través de Reflector de la misma manera que encontró la respuesta). El siguiente ejemplo establece MaxHttpCollectionKeys
en 5000 en ediciones de 32 bits de Windows:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/ASP.NET/1.1.4322.0]
"MaxHttpCollectionKeys"=dword:00001388
Para una edición de Windows de 64 bits, configure la clave debajo de Wow6432Node:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE/SOFTWARE/Wow6432Node/Microsoft/ASP.NET/1.1.4322.0]
"MaxHttpCollectionKeys"=dword:00001388
Solo quiero agregar mis $ 0.02 aquí para las personas que ven la rareza.
Si su aplicación guarda información de la página en ASP.NET ViewState y supera el umbral del servidor web, se encontrará con este problema. En lugar de aplicar el problema de la solución web.config de inmediato, es posible que desee analizar primero la optimización de su código.
Ver código fuente, buscar campos ocultos de más de 1000 estados de vista y tiene su problema.
ThrowIfMaxHttpCollectionKeysExceeded()
también se ha agregado a System.Web.HttpCookieCollection
.
Parece que cuando se llama a HttpCookieCollection.Get()
se llama internamente a HttpCookieCollection.AddCookie()
, que luego llama a 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);
}
}
Lo que estamos viendo es que, durante un par de horas, el sitio web se vuelve cada vez más lento y con más errores, hasta que comienza a lanzar el InvalidOperationExcpetion
. Luego reciclamos el grupo de aplicaciones, que soluciona el problema por unas horas más.