ASP.NET MS11-100: come posso modificare il limite sul numero massimo di valori di modulo pubblicati?


196

Recentemente Microsoft (12-29-2011) ha rilasciato un aggiornamento per risolvere diverse gravi vulnerabilità della sicurezza in .NET Framework. Una delle correzioni introdotte da MS11-100 mitiga temporaneamente un potenziale attacco DoS che coinvolge collisioni della tabella hash. Sembra che questa correzione rompe le pagine che contengono molti dati POST. Nel nostro caso, su pagine con elenchi di caselle di controllo molto grandi. Perché dovrebbe essere così?

Alcune fonti non ufficiali sembrano indicare che MS11-100 pone un limite di 500 articoli postback. Non riesco a trovare una fonte Microsoft che lo confermi. So che View State e altre funzionalità del framework assorbono parte di questo limite. C'è qualche impostazione di configurazione che controlla questo nuovo limite? Potremmo passare dall'uso delle caselle di controllo ma funziona piuttosto bene per la nostra situazione particolare. Vorremmo anche applicare la patch perché protegge da alcune altre cose brutte.

Fonte non ufficiale che discute il limite di 500:

Il bollettino risolve il vettore di attacco DOS fornendo un limite al numero di variabili che possono essere inviate per una singola richiesta POST HTTP. Il limite predefinito è 500, che dovrebbe essere sufficiente per le normali applicazioni Web, ma comunque abbastanza basso da neutralizzare l'attacco, come descritto dai ricercatori sulla sicurezza in Germania.

EDIT: codice sorgente con esempio di limite (che sembra essere 1.000, non 500) Creare un'app MVC standard e aggiungere il seguente codice alla vista indice principale:

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

Questo codice ha funzionato prima della patch. Non funziona dopo. L'errore è:

[InvalidOperationException: operazione non valida a causa dello stato corrente dell'oggetto.]
System.Web.HttpValueCollection.ThrowIfMaxHttpCollectionKeysExceeded () +82 System.Web.HttpValueCollection.FillFromEncodedBytes (Byte [] bytes, Encoding.Web + +1)
. HttpRequest.FillInFormCollection () +307


Che ne dici di fare qualche lavoro aggiuntivo e pubblicare la sezione in cui si dice specificamente 500.
OO

3
Questa è la cosa. Non esiste una sezione (di Microsoft). Solo da commentatori non ufficiali che potrebbero o meno sapere di cosa stanno parlando. Ho comunque pubblicato un link e uno snippet.
colithium,

1
@Andrew: L'unica "lista multi-selezione" che mi viene in mente sarebbe la ListBox con SelectionMode impostato su Multiple. Questo infatti potrebbe eventualmente pubblicare più valori. Tuttavia, la domanda menziona "elenchi a discesa". Attendiamo quindi eventuali commenti dall'autore della domanda.
Wiktor Zychla,

1
Una recente domanda su questo argomento ha determinato che la correzione ha mitigato il DOS limitando il numero di post.
John Saunders,

1
Vedere support.microsoft.com/kb/2661403 per i dettagli al riguardo.

Risposte:


275

Prova ad aggiungere questa impostazione in web.config. Ho appena provato questo su .NET 4.0 con un progetto ASP.NET MVC 2 e con questa impostazione il tuo codice non genera:

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

Ora dovrebbe funzionare (dopo aver applicato l'aggiornamento di sicurezza) per modificare il limite.


Non avevo ancora aggiornato la mia macchina, quindi usando Reflector ho controllato la classe HttpValueCollection e non aveva il ThrowIfMaxHttpCollectionKeysExceededmetodo:

inserisci qui la descrizione dell'immagine

Ho installato KB2656351 (aggiornamento per .NET 4.0), ricaricato gli assembly in Reflector e il metodo è apparso:

inserisci qui la descrizione dell'immagine

Quindi quel metodo è decisamente nuovo. Ho usato l' opzione Disassembla in Reflector e da quello che posso dire dal codice controlla un'impostazione app:

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

Se non trova il valore nel file web.config, lo imposterà su 1000 in System.Web.Util.AppSettings.EnsureSettingsLoaded(una classe statica interna):

 _maxHttpCollectionKeys = 0x3e8;

Inoltre, due giorni fa Alexey Gusarov ha twittato su questa impostazione:

Ed ecco una risposta ufficiale da una domanda e risposta con Jonathan Ness (Security Development Manager, MSRC) e Pete Voss (Sr. Response Communications Manager, Trustworthy Computing):

D: AppSettings.MaxHttpCollectionKeys è il nuovo parametro che contiene il numero massimo di voci del modulo?

A: Sì, lo è.


25
Meraviglioso. Queste sono le risposte che mi fanno innamorare di StackOverflow
colithium

4
Mi ha davvero aiutato, vorrei avere un altro account in modo da poter dare +2 :)
misha

1
può essere aggiornato in applicationhost.config per l'intero server? o machine.config?
Andryuha,

1
Un modo per controllare questo limite a livello di pagina? (Anche chiesto qui e qui .)
Mike Guthrie,

1
Alcune persone hanno suggerito di rivedere la pagina Web in quanto non dovrebbe contenere questi campi di molti moduli. Ma abbiamo avuto uno scenario molto valido per questo errore: il carrello della spesa in uno dei siti di e-commerce del nostro cliente aveva molti articoli e questo errore era registrato quando stava accedendo alla pagina. In tali casi, l'opzione migliore è quella di ignorare il valore massimo.
Ankur-m

18

Per quelli di voi che usano ancora .NET 1.1, questa impostazione non è configurata tramite web.config - si tratta di un'impostazione del registro (suggerimento per michielvoo, poiché l'ho scoperto solo tramite Reflector nello stesso modo in cui ha trovato la risposta). L'esempio seguente imposta MaxHttpCollectionKeys5000 su edizioni a 32 bit di Windows:

Windows Registry Editor Version 5.00

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

Per un'edizione di Windows a 64 bit, impostare la chiave in Wow6432Node:

Windows Registry Editor Version 5.00

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

Hai qualche informazione sul fatto che 5000 sia un valore ragionevolmente sicuro rispetto all'attacco DoS che questa correzione di sicurezza dovrebbe mitigare? Stiamo cercando di utilizzare lo stesso valore 5000, ma non riesco a trovare alcuna informazione sulla relazione tra numero di valori e tempo della CPU consumato per richiesta in un attacco ...
Tao,

4

Voglio solo aggiungere i miei $ 0,02 qui per le persone che vedono la stranezza.

Se l'applicazione inserisce le informazioni sulla pagina in ASP.NET ViewState e supera la soglia del server Web, si verificherà questo problema. Invece di applicare subito il problema di correzione web.config, potresti voler prima dare un'occhiata all'ottimizzazione del codice.

Visualizza sorgente e cerca oltre 1000 campi nascosti viewstate e hai il tuo problema.


1000+ campi viewstate? Non c'è solo un campo ViewState nel modulo. Il valore è ciò che aumenta all'aumentare del numero di campi modulo.
Ankur-m

3

ThrowIfMaxHttpCollectionKeysExceeded() è stato anche aggiunto a System.Web.HttpCookieCollection .

Sembra che quando HttpCookieCollection.Get()viene chiamato, sta chiamando internamente HttpCookieCollection.AddCookie(), che poi sta chiamando 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);
    }
}

Quello che stiamo vedendo è che nel giro di un paio d'ore il sito web diventa progressivamente più lento e più intenso, fino a quando non inizia a lanciare InvalidOperationExcpetion. Quindi ricicliamo il pool di app, che risolve il problema per qualche ora in più.


Il limite di conteggio dei cookie è una buona cattura; Per il rallentamento e il buggy che descrivi, sai se ha effettivamente a che fare con il conteggio dei cookie nelle richieste? Hai controllato le richieste del cliente che stai ricevendo? (la tua app sta facendo intenzionalmente qualcosa con un numero elevato di cookie?)
Tao,

1
si è scoperto che avevamo un CookieProvider personalizzato che stava acquisendo erroneamente un riferimento singleton alla richiesta Request.Cookies all'avvio dell'app, quindi su ogni richiesta successiva, avrebbe verificato se esistessero uno o più cookie all'interno della raccolta di cookie statici ... come puoi vedere dal codice sopra, .Net ADDS quel cookie per impostazione predefinita se non viene trovato. Quindi nel tempo, mentre ogni utente accedeva al sistema, venivano aggiunti vari cookie a questa raccolta singleton ... e poiché il sito è stato progettato per funzionare con o senza cookie, questo bug non è mai stato identificato (fino ad ora)
Joshua Barker
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.