Совсем недавно передо мной стояла задача защитить полностью построенное на ajax веб-приложение от CSRF-атаки .
Каков механизм такой атаки? Идея состоит в том, чтобы выполнить запрос с другого сайта, используя учетные данные пользователя.
Например, у нас есть действие по удалению вашей учетной записи.
Если нет защиты от CSRF-атак, мы можем разместить на нужном нам сайте следующий тег:
Сразу после того, как пользователь посетит подготовленную нами страницу и загрузит img-контент, его аккаунт на example.com будет удален.<img src=" http://example.com/login/dropme ">
О защите от этого я расскажу под катом.
Механизм атаки
Суть атаки заключается в установке тега, загружающего контент по URL с другого сайта.Таким тегом может быть img, script, link (для css), iframe и возможно другие, которые мне не сразу пришли в голову.
Стандартные методы защиты и почему они мне не подошли
Есть простой способ защитить его: проверка 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
-
Все О Ноутбуке Toshiba Qosmio-X505-Q885
19 Oct, 24 -
Ян Юань
19 Oct, 24 -
Устал От Этого.
19 Oct, 24