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

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

Ответы [ 4 ]

275 голосов
/ 31 декабря 2011

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

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

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


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

enter image description here

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

enter image description here

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

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

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

 _maxHttpCollectionKeys = 0x3e8;

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

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

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

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

18 голосов
/ 03 января 2012

Для тех из вас, кто все еще использует .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
4 голосов
/ 10 января 2012

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

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

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

3 голосов
/ 06 января 2012

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. Затем мы перезапускаем пул приложений, который устраняет проблему еще на несколько часов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...