ASP.NET MVC 3/4: Противодействие взлому

в 19:36, , рубрики: .net, ASP, asp.net mvc, взлом, защита сайта, метки: , ,

ASP.NET MVC 3/4: Противодействие взлому

Не так давно прочитал очередную статью о SQL-инъекциях на хабре, статья была посвящена правда PHP, завязались споры как нужно поступать с данными от пользователя, через какие функции их прогонять, с PHP знаком поверхностно, но общую картину усвоил. Тогда и родилась идея показать как обстоят дела с безопасностью в ASP.NET MVC.

Прежде всего создадим простой сайт, пошаговое создание описывать не буду, скажу лишь связку используемых технологий: ASP.NET MVC4 и Entity Framework 4.3.1 (ORM для работы с БД). Проект можно будет скачать в конце статьи.

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

Cross-Site Scripting (XSS)


Начнём наш взлом с XSS, будем внедрять скрипты на страницу с помощью добавления комментариев.
Сейчас мы попробуем добавить комментарий со скриптом:

ASP.NET MVC 3/4: Противодействие взлому

Нажимаем добавить комментарий и получаем ошибку, увы до метода мы так и не дошли:

ASP.NET MVC 3/4: Противодействие взлому

Что быстрее всего сделать, чтобы сайт заработал? Конечно отрубить валидацию для метода:

[ValidateInput(false)]

Вот не задача, снова наш скрипт не выполняется:

ASP.NET MVC 3/4: Противодействие взлому

Происходит это потому-что, по умолчанию весь текст кодируется и выводится закодированным, ситуацию может изменить:

@Html.Raw()

Стоит помнить, что пользователю нельзя доверять, необходимо сохранять только проверенный контент, например, как это делает парсер хабра, удаляя потенциально опасный контент. Также с помощью XSS у вас могут быть украдены данные с помощью банально не закрытого тега img, при загрузке страницы конфиденциальные данные могут попасть третьему лицу. Ещё раз повторю, хоть я и привел пример как всё же записать скрипт в базу, но всегда стоит помнить, что в один прекрасный момент может появиться новый разработчик, который добавит ajax фич с использованием jquery и воспользовавшись $.html() вернёт XSS дыру в безопасности.

SQL-инъекция


Для взлома сайта с помощью инъекций я сделал отдельную страницу, на которой есть поле для поиска комментариев по имени автора, делать методы для работы с моделями чисел, bool`овских значений и прочего нет смысла, так как свою строку точно не передашь, на этапе связывания (binding) входных параметров и модели, эти данные будут отсеяны.

ASP.NET MVC 3/4: Противодействие взлому

Собственно сколько я не пытался что-то сделать так и не получилось, всему виной использование ORM, никаких конкатенаций строк там нету, данные передаются параметрами и экранируются. Сложно представить человека, который не используется ORM при работе с БД, если он пишет проект с нуля и нет
ограничений по технологиям, возможно, если используются какие-то старые модули, на переписывание которых нет времени — это можно как-то оправдать, но тогда вся ответственность ложится на разработчика.

Cross-Site Request Forgery (CSRF)


Примером данной атаки может быть, например, какой-нибудь сайт с внутренней валютой и вам достаточно одного POST запроса, чтобы перевести деньги другому пользователю. Злоумышленник делает форму у себя на сайте, где в действии (form action) указывает на другой сайт, создает скрытые параметры: сумму,
кошелек и т.д… Будучи авторизованным на том сайте вы переведёте ему деньги (другие варианты: удаление чего-то, добавления, в общем большинство POST запросов).

Для борьбы с этим в MVC есть хелпер для представления, который должен быть в теле формы:

@Html.AntiForgeryToken()

ASP.NET MVC 3/4: Противодействие взлому

Теперь атрибут для метода (Action) контроллера:

[ValidateAntiForgeryToken]

Проверим, что у нас получилось (я добавил эту логику на страницу с XSS), делаем обычный запрос:

ASP.NET MVC 3/4: Противодействие взлому

Кроме скрытых полей у нас появились и куки:

ASP.NET MVC 3/4: Противодействие взлому

Теперь удалим это скрытое поле и посмотрим на результат (варианта минимум три, удалить из представления, удалить с помощью Firebug и более интересный для меня это через Composer в Fiddler, перетаскиваем удачный запрос и просто удаляем этот параметр в Request Body):

ASP.NET MVC 3/4: Противодействие взлому

Стоит помнить, что данный параметр не генерируется при каждом запросе и перехватив пакет в последующем можно осуществить взлом.

Скрытие информации


Многие не придают этому внимания, но я считаю, что данный пункт весьма важен. Выбирая когда-то замок для металлической двери я узнал, что многие замки вскрываются элементарно с помощью дрели, будь там три толстых ригеля (цилиндра, которые выезжают), но достаточно просверлить одно отверстие в нужном
месте (так сказать нанести точечных удар по слабым местам) и замок открыт. Аналогично, если вы говорите, что у вас такой-то IIS, такая-то версия ASP.NET и т.д. Вы оказываете неоценимую помощь взломщику! Я люблю чистить логи Elmah с кружкой чая и смотреть как у меня на сайте пытаются найти php, mysql, с
помощью чудных сервисов определить какая CMS используется и т.д.

Вот, что сейчас возвращает мой сайт:

ASP.NET MVC 3/4: Противодействие взлому

Убираем X-Powered-By:

<system.webServer>
...
<httpProtocol>
	<customHeaders>
		<remove name="X-Powered-By" />
	</customHeaders>
</httpProtocol>
...
</system.webServer>

Версию ASP.NET:

<system.web>
...
<httpRuntime enableVersionHeader="false" />
...
</system.web>

Версию MVC в Application_Start:

MvcHandler.DisableMvcResponseHeader = true;

И самое сложное — это сервер, для чего мы сделаем HttpModule:

    public class CustomServerHeaderModule : IHttpModule
    {
        public void Init(HttpApplication context)
        {
            context.PreSendRequestHeaders += OnPreSendRequestHeaders;
        }

        public void Dispose() { }

        private void OnPreSendRequestHeaders(object sender, EventArgs e)
        {
            HttpContext.Current.Response.Headers.Set("Server", "Apache 2000 Server"); 
        }
    }

и добавим в конфиге:

  <system.webServer>
	...
    <modules runAllManagedModulesForAllRequests="true">
	...
      <add name="CustomServerHeader" type="HackingMVC.HttpModules.CustomServerHeaderModule" />
    </modules>
	...
  <system.webServer>

В итоге мы получили вот такой результат:

ASP.NET MVC 3/4: Противодействие взлому

Вместо заключения


Не даром ASP.NET славиться своей безопасностью, очень активно развивается MVC, который с каждой версией становится всё интереснее и интереснее. Остались не рассмотрены некоторые моменты, что-то я упустил, а о чём-то достаточно просто упомянуть, в любом случае невозможно рассмотреть столь объемную тему в рамках одной статьи. Стоит заострить внимание на том, что очень важно использовать SSL на сайте, так как в противном случае ваши данные могут быть похищены при авторизации, украдена сессия на любой странице, токен авторизации или любые другие данные, что сводит на нет многую защиту. Помните и о JSON Hijacking и о том, что он не с проста кидает предупреждение, если пытаться получить данные через GET запрос без указания разрешения, таким способом стоит отдавать только те данные, которые не страшно потерять. Я показал лишь часть проблем, с которыми вы можете столкнуться и на которые стоит обращать внимание при разработке.

P.S. Приветствуются пожелания и варианты взлома данного сайта: архив. (11,6 Мб, так как в солюцию включены скаченные NuGet пакеты)

Автор: eforce

  1. Глеб:

    Спасибо, за статью!

* - обязательные к заполнению поля