Защита Ajax-Приложений От Атак Межсайтового Запроса (Csrf)

Совсем недавно передо мной стояла задача защитить полностью построенное на ajax веб-приложение от CSRF-атаки .

Каков механизм такой атаки? Идея состоит в том, чтобы выполнить запрос с другого сайта, используя учетные данные пользователя.

Например, у нас есть действие по удалению вашей учетной записи.

example.com/login/dropme .

Если нет защиты от CSRF-атак, мы можем разместить на нужном нам сайте следующий тег:

  
  
   

<img src=" http://example.com/login/dropme ">

Сразу после того, как пользователь посетит подготовленную нами страницу и загрузит img-контент, его аккаунт на example.com будет удален.

О защите от этого я расскажу под катом.



Механизм атаки

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

Таким тегом может быть img, script, link (для css), iframe и возможно другие, которые мне не сразу пришли в голову.



Защита ajax-приложений от атак межсайтового запроса (CSRF)



Стандартные методы защиты и почему они мне не подошли

Есть простой способ защитить его: проверка HTTP_REFERER. Меня это не устроило, потому что браузер в анонимном режиме может не отправлять этот заголовок.

В этом случае такой атаке подвергнутся все «анонимные» пользователи.

Есть более продвинутый метод защиты: добавление токена в url и проверка токена при совершении действия.

Почему мне это не понравилось? Есть готовое приложение, в котором уже более 100 ссылок на различные страницы и действия, они выполнены в коде в виде , а не в виде вызова функции с передачей url, соответственно вам придется редактировать еще 100 мест. Есть риск что-то забыть.



Решение

Решение было найдено быстро.

Поскольку в приложении все работает через ajax, мы можем добавить в ajax-запрос заголовок с токеном.

В нашем случае это делается в jQuery так:

$.

ajaxSetup({ headers: { 'X-Csrf-Token':token } });

Помимо ajax-запросов, также могут быть открытия новой вкладки и самое главное первый вход в приложение.

Эти запросы не содержат токена, но мы должны их обработать.

Для их обработки мы используем следующее решение.

Если в запросе нет токена, отправьте следующий html-код:

<html> <body> <Эphp echo $loading_text; ?> <script type='text/javascript'> <Эphp /** check img and other left src tags **/ ?> if (parent.document.location.href == document.location.href){ <Эphp /** check iframe **/ ?> document.location.href='<Эphp echo $url; ?>'; } </script> </body> </html>

Здесь $url — это URL-адрес, по которому был сделан запрос с подписью &csrf_token в конце.

Если такой код включен в тег img, script, link, он не будет выполнен и злоумышленник не достигнет цели.

Если код встроен в iframe, то условие if прервет его выполнение.

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

Собственно, отдать его не особо проблематично.

Например, после загрузки страницы example.com/profile мы всегда оказываемся в стране example.com/profileЭcsrf_token= … Соответственно, нам просто нужно извлечь токен из параметра get с помощью js.

Послесловие

Всё описанное выше я организовал в библиотеку и выложил на github .

В этой библиотеке есть несколько ошибок, но я исправлю их, как только у меня будет время.

Эта библиотека уже работает над реальным проектом.

Теги: #Ajax #CSRF #токен #php #jQuery #Ajax #информационная безопасность #php

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.