Csrf token что это

Материал на этой странице устарел, поэтому скрыт из оглавления сайта.

Нельзя говорить про AJAX и не упомянуть про важнейшую деталь его реализации – защиту от CSRF-атак.

CSRF (Cross-Site Request Forgery, также XSRF) – опаснейшая атака, которая приводит к тому, что хакер может выполнить на неподготовленном сайте массу различных действий от имени других, зарегистрированных посетителей.

Какие это действия – отправка ли сообщений, перевод денег со счёта на счёт или смена паролей – зависят от сайта, но в любом случае эта атака входит в образовательный минимум веб-разработчика.

Злая форма

«Классический» сценарий атаки таков:

Вася является залогиненным на сайт, допустим, mail.com . У него есть сессия в куках.

Вася попал на «злую страницу», например хакер пригласил его сделать это письмом или как-то иначе.

На злой странице находится форма такого вида:

При заходе на злую страницу JavaScript вызывает form.submit , отправляя таким образом форму на mail.com .

Сайт mail.com проверяет куки, видит, что посетитель авторизован и обрабатывает форму. В данном примере форма предполагает посылку сообщения.

Итог атаки – Вася, зайдя на злую страницу, ненароком отправил письмо от своего имени. Содержимое письма сформировано хакером.

Защита

В примере выше атака использовала слабое звено авторизации.

Куки позволяют сайту mail.com проверить, что пришёл именно Вася, но ничего не говорят про данные, которые он отправляет.

Иначе говоря, куки не гарантируют, что форму создал именно Вася. Они только удостоверяют личность, но не данные.

Типичный способ защиты сайтов – это «секретный ключ» ( secret ), специальное значение, которое генерируется случайным образом и сохраняется в сессии посетителя. Его знает только сервер, посетителю мы его даже не будем показывать.

Затем на основе ключа генерируется «токен» ( token ). Токен делается так, чтобы с одной стороны он был отличен от ключа, в частности, может быть много токенов для одного ключа, с другой – чтобы было легко проверить по токену, сгенерирован ли он на основе данного ключа или нет.

Для каждого токена нужно дополнительное случайное значение, которое называют «соль» salt .

Формула вычисления токена:

  1. В сессии хранится secret="abcdef" , это значение создаётся один раз.
  2. Для нового токена сгенерируем salt , например пусть salt="1234" .
  3. token = "1234" + ":" + MD5("1234" + ":" + "abcdef") = "1234:5ad02792a3285252e524ccadeeda3401" .

Это значение – с одной стороны, случайное, с другой – имея такой token , мы можем взять его первую часть 1234 в качестве salt и, зная secret , проверить по формуле, верно ли он вычислен.

Не зная secret , невозможно сгенерировать token, который сервер воспримет как правильный.

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

То есть, «честная» форма для отсылки сообщений, созданная на http://mail.com , будет выглядеть так:

При её отправке сервер проверит поле csrf , удостоверится в правильности токена, и лишь после этого отошлёт сообщение.

«Злая страница» при всём желании не сможет сгенерировать подобную форму, так как не владеет secret , и токен будет неверным.

Такой токен также называют «подписью» формы, которая удостоверяет, что форма сгенерирована именно на сервере.

Эта подпись говорит о том, что автор формы – сервер, но ничего не гарантирует относительно её содержания.

Есть ситуации, когда мы хотим быть уверены, что некоторые из полей формы посетитель не изменил самовольно. Тогда мы можем включить в MD5 для формулы токена эти поля, например:

При отправке формы сервер проверит подпись, подставив в неё известный ему secret и присланное значение fields.money . При несовпадении либо secret не тот (хакер), либо fields.money изменено.

Токен и AJAX

Теперь перейдём к AJAX-запросам.

Что если посылка сообщений в нашем интерфейсе реализуется через XMLHttpRequest?

Как и в случае с формой, мы должны «подписать» запрос токеном, чтобы гарантировать, что его содержимое прислано на сервер именно интерфейсом сайта, а не «злой страницей».

Здесь возможны варианты, самый простой – это дополнительная кука.

При авторизации сервер устанавливает куку с именем CSRF-TOKEN , и пишет в неё токен.

Код, осуществляющий XMLHttpRequest, получает куку и ставит заголовок X-CSRF-TOKEN с ней:

Сервер проверяет, есть ли заголовок и содержит ли он правильный токен.

Защита действует потому, что прочитать куку может только JavaScript с того же домена. «Злая страница» не сможет «переложить» куку в заголовок.

Если нужно сделать не XMLHttpRequest, а, к примеру, динамически сгенерировать форму из JavaScript – она также подписывается аналогичным образом, скрытое поле или дополнительный URL-параметр генерируется по куке.

Итого

CSRF-атака – это когда «злая страница» отправляет форму или запрос на сайт, где посетитель, предположительно, залогинен.

Если сайт проверяет только куки, то он такую форму принимает. А делать это не следует, так как её сгенерировал злой хакер.

Для защиты от атаки формы, которые генерирует mail.com , подписываются специальным токеном. Можно не все формы, а только те, которые осуществляют действия от имени посетителя, то есть могут служить объектом атаки.

Для подписи XMLHttpRequest токен дополнительно записывается в куку. Тогда JavaScript с домена mail.com сможет прочитать её и добавить в заголовок, а сервер – проверить, что заголовок есть и содержит корректный токен.

Динамически сгенерированные формы подписываются аналогично: токен из куки добавляется как URL-параметр или дополнительное поле.

CSRF (англ. Сross Site Request Forgery — «межсайтовая подделка запроса», также известна как CSRF) — вид атак на посетителей веб-сайтов, использующий недостатки протокола HTTP. Если жертва заходит на сайт, созданный злоумышленником, от её лица тайно отправляется запрос на другой сервер (например, на сервер платёжной системы), осуществляющий некую вредоносную операцию (например, перевод денег на счёт злоумышленника). Для осуществления данной атаки жертва должна быть аутентифицирована на том сервере, на который отправляется запрос, и этот запрос не должен требовать какого-либо подтверждения со стороны пользователя, которое не может быть проигнорировано или подделано атакующим скриптом.

Данный тип атак, вопреки распространённому заблуждению, появился достаточно давно: первые теоретические рассуждения появились в 1988 году [1] , а первые уязвимости были обнаружены в 2000 году. A сам термин ввёл Peter Watkins в 2001 году.

Основное применение CSRF — вынуждение выполнения каких-либо действий на уязвимом сайте от лица жертвы (изменение пароля, секретного вопроса для восстановления пароля, почты, добавление администратора и т. д.). Также с помощью CSRF возможна эксплуатация отражённых XSS, обнаруженных на другом сервере.

Содержание

Пример [ править | править код ]

Атака осуществляется путём размещения на веб-странице ссылки или скрипта, пытающегося получить доступ к сайту, на котором атакуемый пользователь заведомо (или предположительно) уже аутентифицирован. Например, пользователь Алиса может просматривать форум, где другой пользователь, Боб, разместил сообщение. Пусть Боб создал тег , в котором в качестве источника картинки указал URL, при переходе по которому выполняется действие на сайте банка Алисы, например:

Если банк Алисы хранит информацию об аутентификации Алисы в куки, и если куки ещё не истекли, при попытке загрузить картинку браузер Алисы отправит куки в запросе на перевод денег на счёт Боба, чем подтвердит аутентификацию Алисы. Таким образом, транзакция будет успешно завершена, хотя её подтверждение произойдет без ведома Алисы.

Защита [ править | править код ]

Защищаться должны все запросы, изменяющие данные на сервере, а также запросы, возвращающие персональные или иные деликатные данные.

Наиболее простым способом защиты от данного типа атак является механизм, когда веб-сайты должны требовать подтверждения большинства действий пользователя и проверять поле HTTP_REFERER, если оно указано в запросе. Но этот способ может быть небезопасен, и использовать его не рекомендуется [2] .

Другим распространённым способом защиты является механизм, при котором с каждой сессией пользователя ассоциируется дополнительный секретный уникальный ключ, предназначенный для выполнения запросов. Секретный ключ не должен передаваться в открытом виде, например, для POST запросов ключ следует передавать в теле запроса, а не в адресе страницы. Браузер пользователя посылает этот ключ в числе параметров каждого запроса, и перед выполнением каких-либо действий сервер проверяет этот ключ. Преимуществом данного механизма, по сравнению с проверкой Referer, является гарантированная защита от атак CSRF. Недостатками же являются требование возможности организации пользовательских сессий и требование динамической генерации HTML-кода страниц сайта.

Спецификация протокола HTTP/1.1 [3] определяет безопасные методы запросов, такие как GET, HEAD, которые не должны изменять данные на сервере. Для таких запросов, при соответствии сервера спецификации, нет необходимости применять защиту от CSRF.

Может возникнуть желание подстраховаться и добавить ключ в каждый запрос, но следует иметь в виду, что спецификация HTTP/1.1 [3] допускает наличие тела для любых запросов, но для некоторых методов запроса (GET, HEAD, DELETE) семантика тела запроса не определена, и должна быть проигнорирована. Поэтому ключ может быть передан только в самом URL или в HTTP заголовке запроса. Необходимо защитить пользователя от неблагоразумного распространения ключа в составе URL, например, на форуме, где ключ может оказаться доступным злоумышленнику. Поэтому запросы с ключом в URL не следует использовать в качестве адреса для перехода, то есть исключить переход по такому адресу клиентским скриптом, перенаправлением сервера, действием формы, гиперссылкой на странице и т. п. с целью сокрытия ключа, входящего в URL. Их можно использовать лишь как внутренние запросы скриптом с использованием XMLHttpRequest или обёрткой, например AJAX.

Существенен факт того, что ключ (CSRF токен) может быть предназначен не для конкретного запроса или формы, а для всех запросов пользователя вообще. Поэтому достаточно утечки CSRF токена c URL, выполняющим простое действие или не выполняющего действие вовсе, как защиты от подделки запроса лишается любое действие, а не только то, с которым связан ставший известным URL.

Существует более жёсткий вариант предыдущего механизма, в котором с каждым действием ассоциируется уникальный одноразовый ключ. Такой способ более сложен в реализации и требователен к ресурсам. Способ используется некоторыми сайтами и порталами, такими как Livejournal, Rambler и др. В настоящий момент (2016 год) нет сведений о преимуществе более жёсткого варианта по сравнению с вариантом, в котором используется единственный для каждой сессии секретный ключ [4] .

Промежуточный слой CSRF и шаблонный тег предоставляют легкую-в-использовании защиту против Межсайтовой подделки запроса. Этот тип атак случается, когда злонамеренный Web сайт содержит ссылку, кнопку формы или некоторый javascript, который предназначен для выполнения некоторых действий на вашем Web сайте, используя учетные данные авторизованного пользователя, который посещал злонамеренный сайт в своем браузере. Сюда также входит связанный тип атак, ‘login CSRF’, где атакуемый сайт обманывает браузер пользователя, авторизируясь на сайте с чужими учетными данными.

Первая защита против CSRF атак — это гарантирование того, что GET запросы (и другие ‘безопасные’ методы, определенные в 9.1.1 Safe Methods, HTTP 1.1, RFC 2616) свободны от побочных эффектов. Запросы через ‘небезопасные’ методы, такие как POST, PUT и DELETE могут быть защищены при помощи шагов, описанных ниже.

Как это использовать¶

Для того чтобы включить CSRF защиту для ваших представлений, выполните следующие шаги:

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

В любом шаблоне, который использует POST форму, используйте тег csrf_token внутри элемента

Введите слова для поиска или имя модуля, класса или функции.


[an error occurred while processing the directive]
Карта сайта