Книга: ASP.NET MVC Framework

Управление данными и cookie

Управление данными и cookie

Применение cookie для сохранения информации используется веб-ресурсами очень часто. Практически каждый ресурс реализует с помощью cookie возможность автоматической авторизации пользователя, если он пожелал этого при первой авторизации. Каждый из вас наверняка знает все эти галочки "запомнить меня" на разнообразных ресурсах, которые здорово помогают пользователям, т. к. позволяют не тратить им время и нервы на ввод данных логина, пароля, а порой и замысловатой CAPTCHA-строки.

Однако следует знать, что использование cookie может привести к уязвимости сайта и к раскрытию пользовательских данных. Представим ситуацию: некоторый сайт производит обновление данных на базе строки запроса, полагаясь на произведенную авторизацию пользователя. И разумеется, данный сайт содержит современный механизм авторизации на базе cookie. Может сложиться впечатление, что это абсолютно безопасно, т. к. cookie хранится на компьютере пользователя, а обновление данных невозможно без подтвержденной авторизации. Однако здесь кроется ошибка, которая может привести к серьезному нарушению безопасности. Не будем предполагать, что cookie попросту может быть украден с компьютера пользователя, допустим, что вы предусмотрели такой вариант и кроме cookie проверяете еще и IP-адрес пользователя. Существует более простой вариант атаки и без доступа к cookie. Этот способ предполагает формирование на странице атакуемого сайта изображения с помощью доступного пользователям функционала. Только вместо адреса изображения злоумышленник может подставить строку запроса на модификацию данных. В таком случае все пользователи, зайдя на ресурс, при попытке просмотра картинки выполнят опасную строку запроса от своего имени. И в случае, если через строку запроса можно управлять данными, такой запрос может привести к печальным последствиям.

Мораль такова, что необходимо избегать управления пользовательскими данными через GET-запросы, которые формируются в том числе и строкой запроса. Все запросы, которые так или иначе приводят к модификации, созданию или удалению данных, необходимо оформлять через POST. Однако часто это очень неудобно для разработчика или вовсе невозможно. В таких случаях полезным будет следующее решение:

? для каждой пользовательской сессии формируется некая строка с уникальным значением;

? для всех запросов, которые модифицируют данные пользователя, добавляется некий параметр, содержащий сформированное уникальное значение, например, так: http://mysite/LogOut?hash=328947236401603167, где параметр hash содержит секретное значение, полученное на сервере;

? в функционале, который занимается модификацией данных, производится проверка на переданное значение параметра, в случае если оно отсутствует или не соответствует созданному, предполагается нарушение безопасности;

? злоумышленник не сможет сформировать строку параметра безопасности, т. к. не знает ее, и описанная ранее атака не сможет быть произведена путем подмены строки запроса.

Однако POST-запросы тоже могут быть подвергнуты атаке. Так, злоумышленнику достаточно сформировать страницу в Интернете, где он создаст форму с автоматической отправкой данных на атакуемый сайт. Ничего не подозревающий пользователь, открыв такую страницу, скрытно для себя авторизуется на своем сайте, предоставляя злоумышленнику выполнять от его имени любые операции. Этот тип атаки получил название Cross-Site Request Forgery (CSRF).

Защита от CSRF может быть осуществлена несколькими путями:

? проверка поля Referer POST-запроса может показать истинный сайт, с которого производился запрос, на основании этой проверки можно защититься от атаки;

? для каждой формы можно сформировать скрытое поле со сформированными секретными данными так, как мы делали это для GET-запросов. При отправке данных с формы скрытое поле также будет отправлено. Нам достаточно просто проверить соответствие переданных данных со сформированными на сервере, чтобы убедиться в том, что POST-запрос безопасен.

ASP.NET MVC содержит вспомогательный набор инструментов для реализации второго сценария защиты от CSRF-атак. Инструменты представляют собой метод расширения Html.AntiForgeryToken, который формирует скрытое поле в разметке:

<% using (Html.BeginForm()) { %>
  ... // здесь набор элементов управления
  <%= Html.AntiForgeryTokenO %>
  <input type="submit" value="Change Password" />
<% } %>

На примере показано использование метода расширения Html.AntiForgeryToken, который в результате сформирует следующую разметку:

<input name="_RequestVerificationToken" type="hidden"
value="71QjBJILoVngYTD+UZ3JTn8KMsJ/Yo48Q2sSOLo6cgpYHc2qOG4UudRujINZtg4L" />

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

[ValidateAntiForgeryToken()]
public ActionResult ChangePassword(string currentPassword,
        string newPassword, string confirmPassword)

Теперь любой POST-запрос к действию ChangePassword приведет к сопоставлению скрытого параметра формы с внутренним, сформированным на сервере. В случае, если параметры не совпадают, возникнет исключение, которое предотвратит несанкционированный доступ (рис. 7.11). Таким образом, проделав несложные действия, вы надежно защитите себя от CSRF-атак.


Оглавление книги


Генерация: 1.095. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз