ASP.NET MS11-100: comment modifier la limite du nombre maximal de valeurs de formulaire publiées?

Microsoft a récemment publié une mise à jour (29-12-2011) pour résoudre plusieurs vulnérabilités de sécurité graves dans .NET Framework. L’un des correctifs introduits par MS11-100 atténue temporairement une éventuelle attaque par déni de service impliquant des collisions de tables de hachage. Il semble que ce correctif casse des pages contenant beaucoup de données POST. Dans notre cas, sur les pages qui ont de très grandes listes de cases à cocher. Pourquoi serait-ce le cas?

Certaines sources non officielles semblent indiquer que MS11-100 impose une limite de 500 aux articles postback. Je ne trouve pas de source Microsoft qui le confirme. Je sais que View State et les autres fonctionnalités du framework manquent une partie de cette limite. Y at-il un paramètre de configuration qui contrôle cette nouvelle limite? Nous pourrions éviter d’utiliser des cases à cocher, mais cela fonctionne plutôt bien pour notre situation particulière. Nous aimerions également appliquer le patch car il protège contre d’autres mauvaises choses.

Source non officielle discutant de la limite de 500:

Le bulletin corrige le vecteur d’attaque DOS en limitant le nombre de variables pouvant être soumises pour une seule requête HTTP POST. La limite par défaut est de 500, ce qui devrait être suffisant pour les applications Web normales, mais suffisamment faible pour neutraliser l’attaque, comme le décrivent les chercheurs en sécurité en Allemagne.

EDIT: code source avec exemple de limite (qui semble être 1 000, pas 500) Créez une application MVC standard et ajoutez le code suivant à la vue d’index principal:

@using (Html.BeginForm()) { 

@for (var i = 0; i < 1000; i++) {
@Html.CheckBox("cb" + i.ToSsortingng(), true)
}
}

Ce code a fonctionné avant le patch. Cela ne marche pas après. L’erreur est:

[InvalidOperationException: l’opération n’est pas valide en raison de l’état actuel de l’object.]
System.Web.HttpValueCollection.ThrowIfMaxHttpCollectionKeysExceeded () +82 System.Web.HttpValueCollection.FillFromEncodedBytes (octets [octets], codage de codage) +111
System.Web.HttpRequest.FillInFormCollection () +307

Essayez d’append ce paramètre dans web.config. Je viens de tester cela sur .NET 4.0 avec un projet ASP.NET MVC 2 et avec ce paramètre, votre code ne lance pas:

    

Cela devrait fonctionner maintenant (après avoir appliqué la mise à jour de sécurité) pour modifier la limite.


Je n’avais pas encore mis à jour ma machine, donc en utilisant Reflector, j’ai vérifié la classe HttpValueCollection et la méthode ThrowIfMaxHttpCollectionKeysExceeded n’existait pas:

entrer la description de l'image ici

J’ai installé KB2656351 (mise à jour pour .NET 4.0), rechargé les assemblys dans Reflector et la méthode est apparue:

entrer la description de l'image ici

Donc, cette méthode est définitivement nouvelle. J’ai utilisé l’option Désassembler dans Reflector et d’après ce que je peux voir du code, il vérifie un AppSetting:

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

S’il ne trouve pas la valeur dans le fichier web.config, il le définira à 1000 dans System.Web.Util.AppSettings.EnsureSettingsLoaded (une classe statique interne):

  _maxHttpCollectionKeys = 0x3e8; 

Aussi, Alexey Gusarov a tweeté à propos de cette configuration il y a deux jours:

Et voici une réponse officielle à une question avec Jonathan Ness (responsable du développement de la sécurité, MSRC) et Pete Voss (directeur principal des communications, Trustworthy Computing):

Q: AppSettings.MaxHttpCollectionKeys est-il le nouveau paramètre contenant le nombre maximal d’entrées de formulaire?

A: Oui c’est le cas

Pour ceux d’entre vous qui utilisent encore .NET 1.1, ce paramètre n’est pas configuré via web.config – il s’agit d’un paramètre de registre (tip to michielvoo, car j’ai découvert cela uniquement via Reflector de la même manière qu’il a trouvé la réponse). L’exemple ci-dessous définit MaxHttpCollectionKeys sur 5000 dans les éditions 32 bits de Windows:

 Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ASP.NET\1.1.4322.0] "MaxHttpCollectionKeys"=dword:00001388 

Pour une édition Windows 64 bits, définissez la clé sous le Wow6432Node:

 Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\ASP.NET\1.1.4322.0] "MaxHttpCollectionKeys"=dword:00001388 

Je veux juste append mon 0.02 $ ici pour les gens qui voient l’étrangeté.

Si votre application stocke des informations de page dans ASP.NET ViewState et dépasse le seuil du serveur Web, vous rencontrerez ce problème. Plutôt que d’appliquer immédiatement le problème de correction de web.config, vous pouvez commencer par optimiser votre code.

Afficher la source et rechercher plus de 1000 champs cachés dans le viewstate et vous avez votre problème.

ThrowIfMaxHttpCollectionKeysExceeded() a également été ajouté à System.Web.HttpCookieCollection .

Il semble que lorsque HttpCookieCollection.Get() est appelé, il appelle en interne HttpCookieCollection.AddCookie() , qui appelle alors ThrowIfMaxHttpCollectionKeysExceeded() .

 public HttpCookie Get(ssortingng 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); } } 

Ce que nous voyons, c’est que sur une période de quelques heures, le site devient de plus en plus lent, jusqu’à ce qu’il commence à lancer InvalidOperationExcpetion . Nous recyclons ensuite le pool d’applications, ce qui corrige le problème pendant quelques heures.