Firma Microsoft niedawno (12-29-2011) wydała aktualizację mającą na celu usunięcie kilku poważnych luk w zabezpieczeniach systemu .NET Framework. Jedna z poprawek wprowadzonych przez MS11-100 tymczasowo ogranicza potencjalny atak DoS obejmujący kolizje tabeli mieszającej. Wygląda na to, że ta poprawka rozbija strony zawierające dużo danych POST. W naszym przypadku na stronach, które mają bardzo duże listy pól wyboru. Dlaczego miałoby tak być?
Niektóre nieoficjalne źródła wydają się wskazywać, że MS11-100 nakłada limit 500 na przedmioty z późniejszym opóźnieniem. Nie mogę znaleźć źródła Microsoft, które to potwierdza. Wiem, że View State i inne funkcje ramowe pochłaniają część tego limitu. Czy jest jakieś ustawienie konfiguracji, które kontroluje ten nowy limit? Możemy zrezygnować z używania pól wyboru, ale działa to całkiem dobrze w naszej konkretnej sytuacji. Chcielibyśmy również zastosować łatkę, ponieważ chroni ona przed innymi nieprzyjemnymi rzeczami.
Nieoficjalne źródło omawiające limit 500:
Biuletyn naprawia wektor ataku DOS, określając limit liczby zmiennych, które można przesłać dla pojedynczego żądania HTTP POST. Domyślny limit to 500, co powinno wystarczyć na normalne aplikacje internetowe, ale wciąż wystarczająco niskie, aby zneutralizować atak, jak opisali badacze bezpieczeństwa w Niemczech.
EDYCJA: Kod źródłowy z przykładem limitu (który wydaje się być 1000, a nie 500) Utwórz standardową aplikację MVC i dodaj następujący kod do głównego widoku indeksu:
@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>
}
Ten kod działał przed łatką. Po tym nie działa. Błąd jest następujący:
[InvalidOperationException: Operacja jest niepoprawna z powodu bieżącego stanu obiektu.]
System.Web.HttpValueCollection.ThrowIfMaxHttpCollectionKeysExceeded () +82 System.Web.HttpValueCollection.FillFromEncodedBytes (kodowanie bajtowe [1])
. HttpRequest.FillInFormCollection () +307
Odpowiedzi:
Spróbuj dodać to ustawienie w pliku web.config. Właśnie przetestowałem to na .NET 4.0 z projektem ASP.NET MVC 2 i przy tym ustawieniu twój kod nie rzuca:
To powinno działać teraz (po zastosowaniu aktualizacji zabezpieczeń), aby zmienić limit.
Nie zaktualizowałem jeszcze komputera, więc za pomocą Reflectora sprawdziłem klasę HttpValueCollection i nie miałem
ThrowIfMaxHttpCollectionKeysExceeded
metody:Zainstalowałem KB2656351 (aktualizacja .NET 4.0), ponownie załadowałem zestawy w Reflector i pojawiła się metoda:
Ta metoda jest zdecydowanie nowa. Użyłem opcji Disassemble w Reflector i z tego, co mogę stwierdzić po kodzie, sprawdza AppSetting:
Jeśli nie znajdzie wartości w pliku web.config, ustawi ją na 1000 in
System.Web.Util.AppSettings.EnsureSettingsLoaded
(wewnętrzna klasa statyczna):Również Aleksiej Gusarow napisał na Twitterze o tym ustawieniu dwa dni temu:
I tu jest oficjalną odpowiedź z Q & A z Jonathan Ness (bezpieczeństwo Development Manager MSRC) i Pete Voss (s Response Communications Manager, Trustworthy Computing):
źródło
Dla tych z was, którzy nadal używają .NET 1.1, to ustawienie nie jest konfigurowane przez web.config - jest to ustawienie rejestru (wskazówka dla Michielvoo, ponieważ odkryłem to tylko przez Reflector w ten sam sposób, w jaki znalazł odpowiedź). Poniższy przykład ustawia
MaxHttpCollectionKeys
na 5000 w 32-bitowych wersjach systemu Windows:W 64-bitowej wersji systemu Windows ustaw klucz pod węzłem Wow6432Node:
źródło
Chcę tylko dodać tutaj 0,02 USD za osoby, które widzą dziwność.
Jeśli aplikacja ukrywa informacje o stronie w ASP.NET ViewState i przekracza próg serwera WWW, napotkasz ten problem. Zamiast od razu rozwiązać problem z web.config, możesz najpierw spróbować zoptymalizować swój kod.
Wyświetl źródło i poszukaj ponad 1000 ukrytych pól stanu wyświetlania, a masz problem.
źródło
ThrowIfMaxHttpCollectionKeysExceeded()
został również dodany doSystem.Web.HttpCookieCollection
.Wygląda na to, że kiedy
HttpCookieCollection.Get()
jest wywoływany, to dzwoni wewnętrznieHttpCookieCollection.AddCookie()
, a następnie dzwoniThrowIfMaxHttpCollectionKeysExceeded()
.Widzimy, że w ciągu kilku godzin strona staje się coraz wolniejsza i bardziej błędna, dopóki nie zacznie się rzucać
InvalidOperationExcpetion
. Następnie przetwarzamy pulę aplikacji, co rozwiązuje problem przez kilka godzin.źródło