Запрос ASP.NET с большим количеством ключей формы, файлов или значимых членов JSON, завершается сбоем с исключением

Применимо к: .NET Framework 3.5 Service Pack 1Windows 7 Service Pack 1Windows 7 Enterprise

Аннотация


Обновление для системы безопасности Microsoft MS11-100 ограничивает максимальное число ключей формы, файлов и членов JSON в HTTP-запросе тысячей. Из-за этого приложения ASP.NET отклоняют запросы, где число этих элементов превышает 1000. HTTP-клиенты, делающие подобные запросы, не будут обслуживаться, а в веб-браузере отобразится сообщение об ошибке. Обычно оно имеет код состояния HTTP 500. Это новое ограничение можно настраивать для отдельных приложений. Инструкции по настройке см. в разделе "Решение".


Проблема


Запросы ASP.NET с большим количеством ключей форм, файлов или значимых членов JSON, получают от сервера ответ об ошибке. В журнале приложения на сервере будет создано предупреждение с источником, указывающим конкретную версию ASP.NET, и идентификатором события 1309. Журнал событий будет содержать одно из следующих сообщений: 


Сообщение 1.
Сведения о приложении:
    Домен приложения: /LM/W3SVC/1/ROOT/<домен>
    Уровень доверия: Средний
    Виртуальный путь приложения: <виртуальный каталог>
    Путь приложения: <путь>
    Имя компьютера: <имя компьютера>
Сведения о процессе:
    ИД процесса: 0001
    Имя процесса: w3wp.exe
    Имя учетной записи: IIS APPPOOL\DefaultAppPool

Сведения об исключении:
Тип исключения: HttpException
Сообщение об исключении: Данные формы, закодированные как URL-адрес, недействительны.
   в System.Web.HttpRequest.FillInFormCollection()
   в System.Web.HttpRequest.get_Form()
   в System.Web.HttpRequest.get_HasForm()
   в System.Web.UI.Page.GetCollectionBasedOnMethod(Boolean dontReturnNull)
   в System.Web.UI.Page.DeterminePostBackMode()
   в System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) 


Сообщение 2.
Сведения о приложении:
    Домен приложения: /LM/W3SVC/1/ROOT/<домен>
    Уровень доверия: Средний
    Виртуальный путь приложения: <виртуальный каталог>
    Путь приложения: <путь>
    Имя компьютера: <имя компьютера>

Сведения о процессе:
    ИД процесса: 0001
    Имя процесса: w3wp.exe
    Имя учетной записи: IIS APPPOOL\DefaultAppPool

Сведения об исключении:
Тип исключения: InvalidOperationException
Сообщение об исключении: Операция недопустима для текущего состояния объекта.
   в System.Web.HttpRequest.FillInFilesCollection()
   в System.Web.HttpRequest.get_Files()
   в FileUpload.Page_Load(Object sender, EventArgs e)
   в System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e)
   в System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e)
   в System.Web.UI.Control.OnLoad(EventArgs e)
   в System.Web.UI.Control.LoadRecursive()
   в System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint

Сообщение 3.
Сведения о приложении:
    Домен приложения: /LM/W3SVC/1/ROOT/<домен>
    Уровень доверия: Средний
    Виртуальный путь приложения: <виртуальный каталог>
    Путь приложения: <путь>
    Имя компьютера: <имя компьютера>

Сведения о процессе:
    ИД процесса: 0001
    Имя процесса: w3wp.exe
    Имя учетной записи: IIS APPPOOL\DefaultAppPool

Сведения об исключении:
Тип исключения: InvalidOperationException
Сообщение об исключении: Операция недопустима для текущего состояния объекта.
   в System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeDictionary(Int32 depth)
   в System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeInternal(Int32 depth)
   в System.Web.Script.Serialization.JavaScriptObjectDeserializer.BasicDeserialize(String input, Int32 depthLimit, JavaScriptSerializer serializer)
   в System.Web.Script.Serialization.JavaScriptSerializer.Deserialize(JavaScriptSerializer serializer, String input, Type type, Int32 depthLimit)
   в System.Web.Script.Serialization.JavaScriptSerializer.DeserializeObject(String input)
   в Failing.Page_Load(Object sender, EventArgs e)
   в System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e)
   в System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e)
   в System.Web.UI.Control.OnLoad(EventArgs e)
   в System.Web.UI.Control.LoadRecursive()
   в System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) 


Файл журнала служб IIS может содержать подобную запись:
2011-01-01 00:00:00 ::1 POST /machine/default.aspx - 80 - ::1 - 500 0 0 187




Причина


Обновление для системы безопасности Microsoft MS11-100 ограничивает в ASP.NET максимальное число ключей формы, файлов и членов JSON в HTTP-запросе тысячей. Это изменение внесено для устранения уязвимости к атакам типа "отказ в обслуживании", описанной в бюллетене по безопасности Майкрософт MS11-100.


Решение


В приложениях, где достигается это ограничение для ключей форм или файлов, можно изменить параметр ASP.NET aspnet:MaxHttpCollectionKeys, как показано в следующем примере файла конфигурации ASP.NET. Этот параметр позволяет устранить ошибку 1 и ошибку 2 в разделе "Проблема". 
<configuration>
<appSettings>
<add key="aspnet:MaxHttpCollectionKeys" value="1000" />
</appSettings>
</configuration>


Примечание. Если вы используете ASP.NET 1.1 на компьютере под управлением 32-разрядной системы, этот параметр можно изменить, добавив значение DWORD в следующий раздел реестра:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ASP.NET\1.1.4322.0\MaxHttpCollectionKeys
Если вы используете ASP.NET 1.1 на компьютере под управлением 64-разрядной системы, этот параметр можно изменить, добавив значение DWORD в следующий раздел реестра:

HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\ASP.NET\1.1.4322.0\MaxHttpCollectionKeys



В приложениях, где это ограничение достигается для членов JSON, можно изменить параметр ASP.NET aspnet:MaxJsonDeserializerMembers, как показано в следующем примере файла конфигурации ASP.NET. Этот параметр позволяет устранить ошибку 3 в разделе "Проблема".
<configuration>
<appSettings>
<add key="aspnet:MaxJsonDeserializerMembers" value="1000" />
</appSettings>
</configuration>



Примечание. Увеличение описанного выше значения повышает восприимчивость сервера к атакам типа "отказ в обслуживании", описанным в бюллетене по безопасности MS11-100.


Ссылки


Для получения дополнительных сведений об информационном бюллетене безопасности ознакомьтесь со следующей статьей TechNet: Дополнительные сведения см. в следующей статье базы знаний Майкрософт:
2638420 MS11-100: уязвимость .NET Framework может привести к несанкционированному получению прав: 29 декабря 2011 г.