2011-12-30 1 views
196

Недавно Microsoft (12-29-2011) выпустила обновление для устранения ряда серьезных уязвимостей безопасности в .NET Framework. Одна из исправлений, введенных в MS11-100, временно смягчает потенциальную атаку DoS с участием столкновений хеш-таблиц. Похоже, это исправление разбивает страницы, содержащие много данных POST. В нашем случае на страницах с очень большими списками флажков. Почему это так?ASP.NET MS11-100: как я могу изменить лимит на максимальное количество опубликованных значений формы?

Некоторые неофициальные источники, по-видимому, указывают, что MS11-100 помещает лимит в 500 пунктов для обратной передачи. Я не могу найти источник Microsoft, который подтверждает это. Я знаю, что View State и другие функциональные возможности удовлетворяют некоторым из этих ограничений. Есть ли какой-либо параметр конфигурации, который контролирует этот новый предел? Мы могли бы отказаться от использования флажков, но это хорошо работает для нашей конкретной ситуации. Мы также хотели бы применить патч, потому что он защищает от других неприятных вещей.

Unofficial source discussing the 500 limit:

Бюллетень фиксирует вектор атаки DOS, обеспечивая ограничение на числа переменных, которые могут быть представлены для одного запроса HTTP POST . Предел по умолчанию - 500, который должен быть достаточным для обычных веб-приложений , но все же достаточно низкий, чтобы нейтрализовать атаку как , описанную исследователями безопасности в Германии.

EDIT: Исходный код с примером предела (который, как представляется, 1000, а не 500) Создание стандартного приложения MVC и добавьте следующий код в главном индексном:

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

Этот код работал перед патчем. После этого он не работает. Ошибка:

[InvalidOperationException:. Операция недопустима из-за текущего состояния объекта]
System.Web.HttpValueCollection.ThrowIfMaxHttpCollectionKeysExceeded() +82 System.Web.HttpValueCollection.FillFromEncodedBytes (Byte [] байт, кодирование Кодирование) +111
System.Web.HttpRequest.FillInFormCollection() +307

+0

Как насчет того, чтобы сделать дополнительную работу и разместить раздел, где он говорит конкретно 500. –

+3

Вот и все. Нет раздела (от Microsoft). Только от неофициальных комментаторов, которые могут или не могут знать, о чем они говорят. В любом случае, я опубликовал ссылку и фрагмент. – colithium

+0

@AndrewBarber Была ссылка на официальный бюллетень в исходном посте, я добавил еще один. – colithium

ответ

274

Попробуйте добавить этот параметр в web.config. Я просто проверил это на .NET 4.0 с проектом ASP.NET MVC 2 и с помощью этой установки кода не бросает:

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

Это должно работать (после того, как вы применили обновление для системы безопасности), чтобы изменить предел.


я не обновил свою машину еще, так что с помощью отражателя я проверил класс HttpValueCollection, и он не имел ThrowIfMaxHttpCollectionKeysExceeded метод:

enter image description here

я установил KB2656351 (обновления для .NET 4.0), перезагружается сборки в отражатель и появился метод:

enter image description here

Так что метод, безусловно, новый. Я использовал разбирайте вариант в отражатель, и от того, что я могу сказать из кода он проверяет AppSetting:

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

Если он не находит значение в файле web.config, она будет установить его 1000 в System.Web.Util.AppSettings.EnsureSettingsLoaded (внутренний статический класс):

_maxHttpCollectionKeys = 0x3e8; 

Кроме того, Алексей Гусаров написал об этом устанавливающих два дня назад:

И here официальный ответ от Q & А с Джонатаном Несс (Security Менеджер по развитию, MSRC) и Пит Восс (Sr. Ответ Communications Manager, Trustworthy Computing):

Q: AppSettings.MaxHttpCollectionKeys новый параметр, который содержит максимальное количество записей форм?

A: Да, это так.

+24

Замечательный. Это те ответы, которые заставляют меня любить stackoverflow – colithium

+4

Это действительно помогло, хотелось бы, чтобы у меня была другая учетная запись, чтобы я мог дать +2 :) – misha

+1

можно ли это обновить в applicationhost.config для всего сервера? или machine.config? – andryuha

18

Для тех из вас, по-прежнему с помощью .NET 1.1, этот параметр не задан с помощью web.config - это параметр реестра (наконечник шляпы к michielvoo, как я только обнаружил это через отражатель так же, как он нашел ответ). В приведенном ниже примере устанавливает MaxHttpCollectionKeys 5000 на 32-разрядных версиях Windows:

Windows Registry Editor Version 5.00 

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

Для 64-разрядной ОС Windows издания, установите ключ под Wow6432Node:

Windows Registry Editor Version 5.00 

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

У вас есть информация о том, является ли 5000 разумно безопасным по отношению к DoS-атаке, что это решение безопасности должно смягчить? Мы смотрим на использование того же значения 5000, но я не могу найти никакой информации о соотношении между количеством значений и временем процессора, потребляемым за запрос в атаке ... – Tao

3

ThrowIfMaxHttpCollectionKeysExceeded() также была добавлена System.Web.HttpCookieCollection.

Похоже, когда вызывается HttpCookieCollection.Get(), он внутренне звонит HttpCookieCollection.AddCookie(), который затем звонит 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); 
    } 
} 

То, что мы видим, что в течение нескольких часов веб-сайт становится все медленнее и buggier, пока она не начнет бросать InvalidOperationExcpetion. Затем мы перерабатываем приложение, которое исправляет проблему еще на несколько часов.

+0

Предел количества файлов cookie является хорошим уловом; Что касается замедления и багги, которые вы описываете, знаете ли вы, имеет ли это что-то общее с количеством файлов cookie в запросах? Вы проверяли запросы клиентов, которые вы получаете? (ваше приложение целенаправленно делает что-то с большим количеством файлов cookie?) – Tao

+1

выясняется, что у нас был пользовательский CookieProvider, который неправильно захватывал однотоновую ссылку на коллекцию Request.Cookies при запуске приложения, а затем при каждом последующем запросе проверит, существует ли в статической коллекции cookie одно или несколько файлов cookie ... как вы можете видеть из приведенного выше кода .Net ADDS, что cookie по умолчанию, если он не найден. Таким образом, со временем, когда каждый пользователь обращался к системе, к этой коллекции Singleton добавлялись различные файлы cookie ... и поскольку сайт был разработан для работы с или без куки-файлов, эта ошибка никогда не была идентифицирована (до сих пор) –

4

Я просто хочу добавить свои $ 0.02 для людей, видящих странность.

Если ваше приложение задерживает информацию о странице в ASP.NET ViewState и превышает порог веб-сервера, вы столкнулись с этой проблемой. Вместо того, чтобы сразу применить проблему исправления web.config, вы можете сначала взглянуть на оптимизацию кода.

View Source, ищите более 1000 скрытых полей в представлении, и у вас есть свои проблемы.

+0

1000+ viewstate поля? Не существует только одного поля ViewState в форме. Значение увеличивается с увеличением числа полей формы. –