Трой Хант (Microsoft Troy Hunt) является Microsoft MVP для разработчика Security и регулярно ведет блоги и твиты о принципах безопасности. Он является создателем ASafaWeb , Automated Security Analyzer для веб-сайтов ASP.NET. Трой заметил, что около 67% веб-сайтов ASP.NET имеют серьезные уязвимости, связанные с конфигурацией. ASafaWeb упрощает сканирование на наличие этих уязвимостей и обеспечивает как исправление, так и дополнительное считывание разрешения.
Трой написал в блоге о чрезмерных заголовках ответа … не позволяйте заголовкам ответа говорить слишком громко .
По умолчанию приложение ASP.NET, работающее в IIS, возвращает много информации о сервере и инфраструктуре через заголовки. Эта информация может использоваться для использования уязвимостей, присутствующих в технологиях, которые идентифицируют заголовки. Если возвращается любой из следующих заголовков ответа, ASafaWeb сообщит о предупреждении для этого сканирования:
- сервер
- X-Powered-By
- X-Сеть САШ-версия
- X-AspNetMvc-версия
Я решил выяснить, как устранить эту уязвимость конфигурации в приложении ASP.NET Web API, работающем в Windows Azure .
Создайте простое приложение ASP.NET Web API
Запустите Visual Studio 2012 от имени администратора (нам понадобятся повышенные привилегии позже при запуске эмулятора Windows Azure).
Создайте новый проект с помощью меню «Файл»> «Создать»> «Проект» и выберите « Веб-приложение ASP.NET MVC 4» . Дайте проекту имя WebAPI, а решению — ExcessiveResponseHeaders . Нажмите ОК. Выберите шаблон веб-API и нажмите ОК.
Щелкните правой кнопкой мыши проект WebAPI в обозревателе решений и выберите « Добавить проект облачной службы Windows Azure» . Будет создан проект WebAPI.Azure с ролью WebAPI, связанной с проектом WebAPI. Проект WebAPI.Azure будет настроен как стартовый проект.
Проект Web API по умолчанию, созданный Visual Studio, будет содержать простой контроллер значений. В этом посте я буду использовать конечную точку REST api / values GET, которая будет просто возвращать список из 2 строк [«value1», «value2»].
Нажмите F5 и запустите проект в эмуляторе Windows Azure.
Удаление заголовков
Используя Fiddler и выдавая GET api / values приложению WebAPI, запущенному в эмуляторе Windows Azure, мы можем наблюдать следующие заголовки ответа:
- Сервер: Microsoft-IIS / 8.0
- X-AspNet-версия: 4.0.30319
- X-Powered-By: ASP.NET
Нет X-AspNetMvc-версия заголовка ответа наблюдается , так как маршрут API / значения управляется в рамках WebAPI. Если вы выпустили GET по следующему URL-адресу: http://127.0.0.1:81/a/a, вы увидите заголовок MVC, когда будет задействована маршрутизация инфраструктуры MVC:
- X-AspNetMvc-версия: 4.0
Чтобы удалить заголовок сервера, мы добавляем следующий метод и код в файл Global.asax.cs в проекте WebAPI :
protected void Application_PreSendRequestHeaders(object sender, EventArgs e) { HttpContext.Current.Response.Headers.Remove("Server"); }
Чтобы удалить заголовок X-AspNetMvc-Version, мы добавляем следующий код в метод Application_Start () в файле Global.asax.cs в проекте WebAPI :
To remove the X-AspNetMvc-Version header we add the following code to the Application_Start() method in the Global.asax.cs file in the WebAPI project:
Чтобы удалить заголовок X-AspNet-Version, убедитесь, что в файле Web.config имеется следующий xml:
<configuration> <system.web> <httpRuntime enableVersionHeader="false" /> </system.web> </configuration>
Чтобы удалить заголовок X-Powered-By, убедитесь, что в файле Web.config имеется следующий xml:
<configuration> <system.webServer> <httpProtocol> <customHeaders> <remove name="X-Powered-By" /> </customHeaders> </httpProtocol> </system.webServer> </configuration>
Снова нажмите F5 в Visual Studio, чтобы запустить приложение с нашими изменениями. Использование Fiddler и отправка GET API / значений в приложение WebAPI теперь показывает, что заголовки были подавлены.
Развертывание этого кода в Windows Azure ( http://pbwebapi.cloudapp.net ) подтверждает, что это решение также работает там.
В Azure работает решение по умолчанию для веб-API (до подавления заголовков):
В Azure работает модифицированное решение Web API (после подавления заголовков):
Есть ли для этого пакет NuGet?
Там всегда есть … И его зовут NWebsec .
Отмените все изменения, сделанные ранее в файлах Global.asax.cs и Web.config . Щелкните правой кнопкой мыши по проекту WebAPI и выберите Управление пакетами NuGet … Найдите NWebsec и установите.
Установка пакета NuGet изменяет файл Web.config в проекте WebAPI, добавляя nwebsec sectionGroup и запись в модулях .
Заголовок X-Powered-By добавляется IIS и не может быть удален в конвейере обработки. Поэтому NWebsec не может удалить его. Чтобы удалить заголовок X-Powered-By, убедитесь, что в файле Web.config имеется следующий xml:
<configuration> <system.webServer> <httpProtocol> <customHeaders> <remove name="X-Powered-By" /> </customHeaders> </httpProtocol> </system.webServer> </configuration>
Чтобы подавить все остальные заголовки, убедитесь, что файл Web.config содержит следующий xml:
<configuration> <nwebsec> <httpHeaderModule> <suppressVersionHttpHeaders enabled="true" /> </httpHeaderModule> </nwebsec> </configuration>
Это было намного лучше. Нам осталось только добавить некоторую конфигурацию в Web.config. Там не было никакого кода.
Пакет NWebsec не подавляет заголовок сервера, а по умолчанию имеет значение Webserver 1.0 — это значение можно настроить в файле Web.config. Все остальные заголовки подавляются, как это видно через Fiddler.
После развертывания обновления в Azure ( http://pbwebapi.cloudapp.net ) подтверждается, что это решение также работает там.
Сканирование с помощью ASafaWeb
Сканирование конечной точки api / values REST нашего приложения Web API по умолчанию с помощью анализатора ASafaWeb возвращает предупреждение о тех же заголовках, которые мы наблюдали с помощью Fiddler.
Сканирование конечной точки api / values REST нашего веб-API с поддержкой NWebsec с помощью анализатора ASafaWeb возвращает предупреждение о тех же заголовках, которые мы наблюдали с помощью Fiddler.
Сканирование конечной точки api / values REST нашего вручную настроенного приложения Web API с помощью анализатора ASafaWeb возвращает предупреждение о заголовке Server: Microsoft-IIS / 8.0 . Это не то, что мы наблюдали через Fiddler.
Но подождите … Что это за просматриваемый URL?
http://pbwebapi.cloudapp.net/api/values/elmah.axd ?
Подлый! В результате этого URL IIS поднял 404, поскольку файл не существует. Это было в обход конвейера обработки и наших попыток подавить заголовки.
Закрытие 404 — дыра не найдена
Мы продолжим с ручной версией нашего кода подавления заголовков — я стремлюсь подавить все заголовки, и пакет NWebsec по-прежнему отправляет заголовок сервера.
Снова есть пакет NuGet, который приходит на помощь. NotFoundMVC автоматически устанавливается во время запуска веб-приложения. Он обрабатывает все различные способы, которыми 404 HttpException обычно генерируется ASP.NET MVC. Это включает в себя отсутствующий контроллер, действие и маршрут.
Щелкните правой кнопкой мыши по проекту WebAPI и выберите Управление пакетами NuGet… Найдите NotFoundMVC и установите.
Пакет NotFoundMVC внесет следующие изменения в файл Web.config в проекте WebAPI. Error.cshtml, размещенный в Views \ Shared, может быть изменен, чтобы предоставить настроенные 404 страницы.
Развертывание в Azure и сканирование конечной точки api / values REST нашего вручную настроенного приложения Web API через анализатор ASafaWeb возвращает PASS.
Но подождите — это еще не все …
Вы думаете, я был бы счастлив с пропуском! Но я видел что-то в одном из URL-адресов, которые пытались использовать анализатор ASafaWeb. В URL был добавлен недопустимый символ. Поэтому я попробовал следующий URL локально:
Почему этот заголовок сервера вернулся? И почему он сейчас сообщает о Microsoft-HTTPAPI / 2.0 ?
Когда вы видите значение заголовка сервера, содержащее Microsoft-HTTPAPI вместо версии IIS, это означает, что драйвер HTTP.SYS обработал запрос и не прошел весь процесс пользовательского режима IIS.
Так как же нам избавиться от этого заголовка сейчас? Этот заголовок добавляется прямо на уровне ядра. Время вырваться из надежной утилиты regedit. Добавьте DisbableServerHeader REG_DWORD со значением 1 к следующему:
- HKLM \ SYSTEM \ CurrentControlSet \ Services \ HTTP \ Parameters
Для этого требуется перезапустить службу HTTP.SYS. Я боролся с сервисными зависимостями, но перезагрузка моей машины обеспечила перезагрузку. Как только это было сделано, недопустимый URL-адрес больше не отображал заголовок сервера.
И наконец — изменение HTTP.SYS в Windows Azure.
Попытка URL с недопустимым символом привела к тому же результату в Windows Azure.
Чтобы отредактировать реестр в веб-роли нашей облачной службы в Windows Azure, нам нужно написать командный файл. Щелкните правой кнопкой мыши проект WebAPI и выберите Добавить> Новый элемент … Добавить текстовый файл с именем Configure_HTTP.SYS.cmd и заполните следующее:
@echo off setlocal set regpath=HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\HTTP\Parameters reg query "%regpath%" /v "DisableServerHeader" if errorlevel 1 ( reg add %regpath% /v DisableServerHeader /t REG_DWORD /d 00000001 shutdown /r /t 0 )
Это добавит запись реестра, если она не существует, и перезагрузит экземпляр. Это произойдет только тогда, когда экземпляр будет повторно подготовлен, поскольку запись реестра больше не будет устанавливаться.
Убедитесь, что для параметра « Действие построения» задано значение « Нет», а для параметра « Копировать в выходной каталог» задано значение « Копировать всегда» для командного файла.
Убедитесь, что командный файл настроен как задача запуска и запущен с повышенными привилегиями. Добавьте следующий XML-файл в файл ServiceDefinition.csdef в проекте WebAPI.Azure:
<Startup> <Task commandLine="Configure_HTTP.SYS.cmd" executionContext="elevated" /> </Startup>
Развертывание в Azure и попытка URL с недопустимым символом теперь приводит к подавлению всех заголовков.
Вывод
Немного поработав, вы можете подавить все заголовки в приложении ASP.NET, работающем в Windows Azure.
Имейте в виду, что удаление этих чрезмерных заголовков — это не серебряная пуля, которая волшебным образом снизит вероятность атаки вашего веб-приложения на 100%. Но добавляя эти дополнительные слои, вы, по крайней мере, можете исключить злоумышленников, которые смотрят на конкретные заголовки ответа, чтобы определить, являетесь ли вы интересной целью.