196 votes

ASP.NET MS11-100: comment puis-je modifier la limite sur le nombre maximum de posté les valeurs d'un formulaire?

Microsoft a récemment (12-29-2011) a publié une mise à jour de l'adresse de plusieurs graves failles de sécurité dans le .NET Framework. L'un des correctifs introduits par MS11-100 temporairement atténue un potentiel d'attaque de déni de service impliquant la table de hachage de collisions. Il apparaît que ce corriger les sauts de pages qui contiennent beaucoup de données POST. Dans notre cas, sur les pages qui ont une très grande case à cocher listes. Pourquoi serait-ce le cas?

Certaines sources non officielles, semblent indiquer que MS11-100 places une limite de 500 sur la publication des articles. Je ne peux pas trouver une source Microsoft qui confirme ce. Je sais que l'État d'Affichage et d'autres fonctionnalités d'infrastructure de manger certains de cette limite. Est-il un paramètre de configuration qui contrôle cette nouvelle limite? Nous pourrions nous passer de l'aide des cases à cocher, mais il fonctionne plutôt bien pour notre cas particulier. Nous aimerions également appliquer le patch, car il protège contre certaines autres choses désagréables.

Source non officielle de discuter de la limite de 500:

Le bulletin résout le DOS vecteur d'attaque en fournissant une limite à la certain nombre de variables qui peuvent être soumis à un seul HTTP POST demande. La limite par défaut est de 500 qui devrait être suffisant pour la normale les applications web, mais encore assez faible pour neutraliser l'attaque comme décrit par les chercheurs en sécurité en Allemagne.

EDIT: le code Source de l'exemple de la limite (qui semble être de 1 000, pas 500) Créer un standard MVC application et ajoutez le code suivant à l'indice principal de la vue:

@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>
}

Ce code a travaillé avant le patch. Il ne fonctionne pas après. L'erreur est:

[InvalidOperationException: Opération n'est pas valide en raison de l'actuelle état de l'objet.]
Système.Web.HttpValueCollection.ThrowIfMaxHttpCollectionKeysExceeded() +82 Système.Web.HttpValueCollection.FillFromEncodedBytes(Byte[] bytes, Encoding) +111
Système.Web.HttpRequest.FillInFormCollection() +307

277voto

michielvoo Points 15413

Essayez d'ajouter ce paramètre dans le web.config. Je viens de testé sur des .NET 4.0 avec un ASP.NET MVC 2 projet et avec ce réglage, votre code n'est pas à jeter:

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

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


Je n'avais pas mis à jour ma machine pourtant, l'utilisation d'un Réflecteur j'ai vérifié le HttpValueCollection classe, et il n'avait pas l' ThrowIfMaxHttpCollectionKeysExceeded méthode:

enter image description here

J'ai installé KB2656351 (mise à jour pour .NET 4.0), reloaded, les assemblées de Réflecteur et la méthode est apparue:

enter image description here

De sorte que la méthode est certainement de nouveau. J'ai utilisé le Démonter option dans le Réflecteur, et de ce que je peux dire d'après le code, il vérifie une AppSetting:

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

S'il ne trouve pas la valeur dans le web.fichier de config, il va le mettre à 1000 en System.Web.Util.AppSettings.EnsureSettingsLoaded (interne d'une classe statique):

 _maxHttpCollectionKeys = 0x3e8;

Aussi, Alexey Gusarov tweeté à propos de ce paramètre il y a deux jours:

Et ici est une réponse officielle à partir d'un Q&A avec Jonathan Ness (Security Development Manager, MSRC) et Pete Voss (Sr Réponse du directeur de la Communication, Informatique de Confiance):

Q: Est AppSettings.MaxHttpCollectionKeys le nouveau paramètre qui contient le nombre maximal d'entrées de formulaire?

A: Oui, il est.

18voto

terranwannabe Points 181

Pour ceux d'entre vous utilisent encore .NET 1.1, ce paramètre n'est pas configuré via le web.config - c'est un paramètre de registre (hat tip pour michielvoo, que je n'ai découvert ce par le biais de Réflecteur de la même façon qu'il a trouvé la réponse). L'exemple ci-dessous définit MaxHttpCollectionKeys de 5000 sur 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 un Windows 64 bits edition, mis la clé sous la Wow6432Node:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\ASP.NET\1.1.4322.0]
"MaxHttpCollectionKeys"=dword:00001388

4voto

Eyeless Whim Points 147

Je veux juste ajouter que mon $0.02 ici pour les gens de voir l'étrangeté.

Si votre application vous permet de ranger votre page d'informations sur ASP.NET ViewState, et dépasse le serveur web seuil, vous allez rencontrer ce problème. Plutôt que d'appliquer le web.config résoudre le problème tout de suite, vous voudrez peut-être jeter un coup d'oeil à l'optimisation de votre premier code.

L'affichage de la Source, et de regarder pour plus de 1000 viewstate champs cachés, et vous avez votre problème.

3voto

Joshua Barker Points 169

ThrowIfMaxHttpCollectionKeysExceeded() a également été ajoutée au Système.Web.HttpCookieCollection.

Ça ressemble quand HttpCookieCollection.Get() est appelée, elle est interne appel HttpCookieCollection.AddCookie(), qui appelle 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);
    }
}

Ce que nous voyons, c'est que sur une période de quelques heures, le site devient progressivement plus lent et buggier, jusqu'à ce qu'il commence à jeter le InvalidOperationExcpetion. Nous avons ensuite recycler l'application de la piscine, ce qui résout le problème pour quelques heures de plus.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X