ASP.NET MS11-100: как изменить ограничение на максимальное количество отправляемых значений формы?

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

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

Неофициальный источник, обсуждающий лимит 500:

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

РЕДАКТИРОВАТЬ: Исходный код с примером лимита (который выглядит как 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 [] bytes, Encoding encoding) +111
System.Web.HttpRequest.FillInFormCollection () +307

5 ответов

Решение

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

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

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


Я еще не обновил свой компьютер, поэтому с помощью Reflector я проверил класс HttpValueCollection, и у него не было ThrowIfMaxHttpCollectionKeysExceeded метод:

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

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

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

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

 _maxHttpCollectionKeys = 0x3e8;

Также Алексей Гусаров написал в твиттере об этой настройке два дня назад:

И вот официальный ответ от Q&A с Джонатаном Нессом (Менеджер по развитию безопасности, MSRC) и Питом Воссом (Старший менеджер по коммуникациям Response, Надежные вычисления):

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

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

Для тех из вас, кто все еще использует.NET 1.1, этот параметр не настроен через web.config - это параметр реестра (подсказка для michielvoo, поскольку я обнаружил это только через Reflector так же, как он нашел ответ). Пример ниже устанавливает 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 установите ключ под узлом Wow6432:

Windows Registry Editor Version 5.00

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

Я просто хочу добавить свои 0,02 доллара здесь, чтобы люди увидели странности.

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

Просматривайте источник и ищите более 1000 скрытых полей viewstate, и у вас возникла проблема.

Если вы используете ASP.NET CORE, вы можете установить этот параметр в Startup#ConfigureServices.

      services.Configure<FormOptions>(options => options.ValueCountLimit = 1000); // you may want to adjust this limit

Ссылка:StackOverflow

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);
    }
}

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

Другие вопросы по тегам