Неверный csrf токен проверьте включена ли поддержка cookie в веб браузере

Обновлено: 07.07.2024

Промежуточное ПО CSRF и теги шаблонов упрощают защиту от атак с подделкой межсайтовых запросов . Этот тип атаки происходит, когда вредоносный веб-сайт содержит ссылку, кнопку формы или фрагмент кода JavaScript, который предназначен для выполнения действия на вашем веб-сайте с использованием учетных данных авторизованного пользователя, который посещает вредоносный сайт в своем браузере. Также рассматривается родственный тип атаки: «CSRF login», когда атакующий сайт обманывает браузер пользователя, подключаясь к сайту с чужими учетными данными.

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

Чтобы воспользоваться преимуществами защиты CSRF в представлениях, сделайте следующее:

По умолчанию промежуточное ПО CSRF включено в настройках MIDDLEWARE . Если вы переопределите этот параметр, помните, что это 'django.middleware.csrf.CsrfViewMiddleware' должно происходить до того, как промежуточное ПО, которое полагается на CSRF-атаки, уже было отражено.

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

В любом шаблоне, который использует форму POST, используйте тег шаблона csrf_token внутри тега HTML, <form> если форма ссылается на внутренний URL-адрес, например:

С другой стороны, этого не следует делать для форм POST, нацеленных на внешние URL-адреса, поскольку это приведет к раскрытию токена CSRF и, таким образом, приведет к уязвимости.

В соответствующих функциях просмотра проверьте, что RequestContext используется для создания ответа, чтобы он работал правильно. Если вы используете функцию , общие представления или дополнительные приложения, не нужно беспокоиться, потому что все эти представления используют . render() RequestContext

Рекомендуемым источником для токена является файл cookie csrftoken , который будет присутствовать, если у вас включена защита CSRF для вашего представления, как показано выше.

Файл cookie CSRF имеет имя csrftoken по умолчанию, но вы можете изменить это имя в настройках CSRF_COOKIE_NAME .

Получить токен можно так:

Приведенный выше код можно упростить, заменив библиотеку Cookie JavaScript getCookie :

Маркер CSRF также присутствует в DOM, но только если он явно включен с помощью тега csrf_token в шаблоне. Файл cookie будет содержать стандартный токен; он CsrfViewMiddleware предпочтет cookie токену DOM. В любом случае вы гарантированно получите cookie, если токен присутствует в DOM, поэтому лучше использовать cookie!

Если представление не использует шаблон, содержащий тег csrf_token , Django может не установить файл cookie CSRF. Такая ситуация часто возникает в случаях, когда формы динамически добавляются на страницу. Чтобы решить эту проблему, Django предоставляет вид декоратора , который заставляет использовать куки: ensure_csrf_cookie() .

Установка токена для запроса AJAX ¶

Наконец, вам нужно установить заголовок для вашего запроса AJAX. Используя API fetch () :

Использование CSRF в шаблонах Jinja2 ¶

Jinja2 Механизм шаблонов Django добавляет контекст всех шаблонов, что эквивалентно языку шаблонов Django. Например : >

Метод декоратора ¶

Вместо того, чтобы добавлять CsrfViewMiddleware в качестве общей защиты, вы можете использовать декоратор csrf_protect , который предлагает точно такую ​​же функциональность, для конкретных представлений, которые нуждаются в защите. Этот декоратор следует использовать как в представлениях, которые включают в себя токен CSRF, так и в представлениях, которые принимают данные формы POST. (Часто это одна и та же функция просмотра, но не всегда).

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

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

Если вы используете представления на основе классов, вы можете обратиться к разделу «Украшение представлений на основе классов» .

Отклоненные запросы ¶

По умолчанию пользователю возвращается ответ «403 Forbidden», если входящий запрос не удовлетворяет проверкам, выполненным пользователем CsrfViewMiddleware . Как правило, это должно появляться только в том случае, если это настоящая атака «Подделка межсайтового запроса» или когда из-за ошибки программирования токен CSRF не был включен в форму. типа POST.

Однако страница с ошибкой не очень приятная, поэтому вы можете предоставить собственное представление для решения этой проблемы. Для этого определите настройку CSRF_FAILURE_VIEW .

Сбои CSRF регистрируются как предупреждения в журнале django.security.csrf .

Операция ¶

Защита CSRF основана на следующем:

Файл cookie CSRF, основанный на случайном секретном значении, к которому другие сайты не будут иметь доступа.

Этот файл cookie создается промежуточным программным обеспечением CsrfViewMiddleware . Он отправляется с каждым вызванным ответом django.middleware.csrf.get_token() (функция, используемая внутри для получения токена CSRF), если он еще не был определен для запроса.

Для защиты от атак BREACH токен - это не просто секрет; к секрету добавляется случайная маска, которая используется для его шифрования.

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

Скрытое поле формы с именем «csrfmiddlewaretoken» присутствует во всех исходящих формах POST. Значение этого поля, опять же, является значением секрета с маской, которая добавляется к нему и используется для его шифрования. Маска регенерируется при каждом вызове, get_token() поэтому значение поля формы изменяется в каждом таком ответе.

Это действие выполняется тегом шаблона.

При проверке значения поля csrfmiddlewaretoken только секретное значение, а не полный токен, сравнивается с секретным значением содержимого cookie. Это позволяет использовать постоянно меняющиеся токены. Хотя каждый запрос может использовать свой токен, секретное значение остается общим для всех.

Эта проверка выполняется промежуточным программным обеспечением CsrfViewMiddleware .

Расширение принятых рефереров за пределы текущего хоста или домена cookie можно выполнить с помощью этой настройки CSRF_TRUSTED_ORIGINS .

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

Удаление заголовка Referer

Чтобы избежать раскрытия URL-адреса реферера сторонним сайтам, может быть желательно отключить реферер в тегах <a> вашего сайта. Например, можно использовать тег или включить заголовок . Из-за строгого контроля реферера в защите CSRF для запросов HTTPS эти методы приводят к сбоям CSRF для «небезопасных» запросов методов. Лучше использовать альтернативы, такие как ссылки на сторонние сайты. <meta name="referrer" content="no-referrer"> Referrer-Policy: no-referrer <a rel="noreferrer" . >"

Кеширование ¶

Если тег шаблона csrf_token используется шаблоном (или функция get_token вызывается другим способом), промежуточное ПО CsrfViewMiddleware добавляет в ответ файл cookie и заголовок . Это означает, что промежуточное ПО будет хорошо работать с промежуточным ПО кеширования, если оно используется в соответствии с инструкциями ( должно быть помещено в настройки перед любым другим промежуточным ПО). Vary: Cookie UpdateCacheMiddleware

Однако, если вы используете декораторы кеша для отдельных представлений, промежуточное ПО CSRF еще не сможет установить заголовок Vary или файл cookie CSRF, и ответ будет кэшироваться без них. Другой. В этом случае в представлениях, которые требуют вставки токена CSRF, вы должны django.views.decorators.csrf.csrf_protect() сначала использовать декоратор функции :

Если вы используете представления на основе классов, вы можете обратиться к разделу «Украшение представлений на основе классов» .

Тесты ¶

Ограничения ¶

Поддомены сайта могут размещать файлы cookie на клиенте для всего домена. Установив файл cookie и используя соответствующий токен, поддомены смогут обойти защиту CSRF. Единственный способ избежать этого - убедиться, что поддомены контролируются доверенными пользователями (или, по крайней мере, не могут устанавливать файлы cookie). Обратите внимание, что даже без CSRF существуют другие уязвимости, такие как фиксация сеанса, из-за которых выдача субдоменов ненадежным третьим сторонам является плохой идеей; эти уязвимости не могут быть легко устранены с помощью текущих браузеров.

Особые случаи ¶

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

Утилиты ¶

Приведенные ниже примеры относятся к представлениям на основе функций. Если вы используете представления на основе классов, вы можете обратиться к разделу «Украшение представлений на основе классов» .

Этот декоратор отмечает представление как освобожденное от защиты, обеспечиваемой промежуточным программным обеспечением. Пример:

Обычно тег шаблона csrf_token не работает, если не CsrfViewMiddleware.process_view использовался аналогичный аналог csrf_protect . Декоратор представления requires_csrf_token можно использовать, чтобы убедиться, что тег шаблона работает. Этот декоратор работает аналогично csrf_protect , но никогда не отклоняет входящий запрос.

Этот декоратор заставляет представление отправлять файл cookie CSRF.

Сценарии ¶

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

Большинство представлений требуют защиты CSRF, но некоторые нет.

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

CsrfViewMiddleware.process_view не используется ¶

Бывают случаи, когда он CsrfViewMiddleware.process_view не будет выполнен до вашего просмотра - например, обработчики ошибок 404 и 500 - но вам все равно нужен токен CSRF в форме.

Незащищенное представление требует токена CSRF ¶

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

Решение: используйте с csrf_exempt() последующим requires_csrf_token() (т.е. requires_csrf_token должен быть самым внутренним декоратором).

Вид нуждается в защите для определенного пути ¶

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

Обходной путь : используйте csrf_exempt() для всей функции просмотра и, в csrf_protect() частности, для пути, который необходимо защитить. Пример:

Решение: используйте ensure_csrf_cookie() в представлении, которое отправляет страницу.

Встроенные и многоразовые приложения ¶

Поскольку разработчик может отключить промежуточное ПО CsrfViewMiddleware , все затронутые представления в приложениях Contrib Django используют декоратор, csrf_protect чтобы гарантировать, что эти приложения защищены от атак CSRF. Рекомендуется, чтобы разработчики других многоразовых приложений, которые хотят предложить те же гарантии, также использовали декоратор csrf_protect для своих представлений.

Настройки ¶

Для управления поведением Django против CSRF можно использовать ряд настроек:

Часто задаваемые вопросы ¶

Является ли отправка пары произвольных токенов CSRF (данные cookie и POST) уязвимостью? ¶

Некоторые инструменты аудита безопасности сообщают об этом как о проблеме, но, как упоминалось выше, злоумышленник не может украсть файл cookie CSRF из браузера пользователя. Возможность «украсть» или изменить собственный токен с помощью Firebug, инструментов разработчика Chrome и т. Д. не означает, что это уязвимость.

Проблематично ли, что защита Django CSRF по умолчанию не привязана к сеансу? ¶

Нет, сознательно нет. Отсутствие привязки защиты CSRF к сеансу позволяет использовать защиту на таких сайтах, как pastebin, которые разрешают отправку данных анонимным пользователям, у которых нет сеанса.

Если вы хотите сохранить токен CSRF в сеансе пользователя, установите параметр CSRF_USE_SESSIONS .

Почему после входа в систему пользователь может получить ошибку проверки CSRF? ¶


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

Замечание 1: если подходить формально, то CSRF является атакой, а не уязвимостью, как и XSS. Уязвимостью является неправильная обработка входных данных, а CSRF это использует.
Замечание 2: если какие-то ошибки показались вам очевидными и не заслуживающими упоминания, то я рад за вас. Однако данный материал основан на реальных уязвимостях крупных сайтов, а каждый пункт показывает ошибку какой-либо команды разработчиков, обернувшуюся дырой в безопасности.

Список ошибок:

1) Полностью отсутствует защита от CSRF.

По своему опыту могу сказать, что в настоящее время это — самая распространенная ошибка. Ее можно встретить как на малопосещаемых блогах, так и на крупных проектах. Единственная уважительная причина не использовать защиту от данного вида атак — сайт не хранит никакие пользовательские данные, а вы не используете панель администратора для редактирования материалов.

2) Защищены не все запросы.
3) Использование для защиты от CSRF чего-либо, кроме токенов.

Как насчет использования капчи? Я слышал достаточно большое количество вопросов от разработчиков о возможности их использования для защиты от атаки. Мой однозначный ответ — нет. Во-первых, вы явно не будете заставлять пользователя вводить капчу на каждый чих: это приведет к ошибке № 2. Во-вторых, далеко не все способы реализации капч обеспечат вас должной защитой, которую злоумышленник не сможет обойти. Поскольку эта тема является весьма спорной и актуальной, в дальнейшем я посвящу ей отдельную статью.

Для защиты от CSRF вы должны использовать анти-CSRF токены и только их. Лишь они обеспечивают должную защиту ваших сайтов. В общих чертах о механизме токенов рассказано в Википедии:

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

Данную ошибку я встретил сразу на нескольких крупных сайтах рунета в разных вариациях. Например, один из сайтов использовал токены вида «Имя_пользователя.Текущее_время.Длинное_случайное_число». При этом проверялось только соответствие имени пользователя в токене и логина того, от чьего имени был отправлен запрос. Это немного усложняет атаку, но не делает ее невозможной.

6) Возможность использовать один токен для разных пользователей.

Данную ошибку я встретил один раз, но на достаточно крупном сайте, так что считаю необходимым упомянуть ее. Злоумышленник мог зарегистрировать новый аккаунт на сайте, скопировать токен из исходного кода страницы и использовать его для CSRF. Не допускайте такой ошибки, так как она полностью уничтожает все плюсы токенов на вашем сайте.

7) Недостаточная длина токена.

Ваш токен должен быть настолько длинным, чтобы злоумышленник потратил на его подбор как минимум столько же времени, сколько и на подбор пароля пользователя. Я встречал токены из 2 символов, они не сильно помогут, если кто-то очень сильно захочет осуществить CSRF-атаку.

8) Предсказумые токены.

При разработке алгоритма генерации токена обязательно используйте случайные данные в токене (совет актуален, если вы разрабатываете всю систему с нуля. В случае использования фреймворка или CMS вы должны полагаться на их разработчиков). Поверьте, токен вида «md5(user_id)» — очень плохая идея.

9) Отсутствие токенов в админ-панели или системе для сотрудников техподдержки.

Даже если весь доступный вашим пользователям сайт защищен от CSRF, то не стоит забывать про панель администратора. В одной известной в узких кругах биллинг-системе было много CSRF именно в панели администратора (хотя они были и в публичной части системы, но это не так важно). И любой, кто знал структуру запросов, мог использовать CSRF-атаку на сотрудника техподдержки и получить доступ к данным всех клиентов компании, использующей данную биллинг-систему. Единственная проблема — необходимо узнать структуру запросов: для этого можно использовать социальную инженерию, скачать копию в открытых источниках или просто взломать менее защищенный сайт, использующий такую же систему.

10) Передача токенов в открытом виде, особенно в GET-запросах.

Наличие этих ошибок даже на крупных и серьезных сайтах показывает, что проблема защиты от CSRF-атак стоит достаточно остро. Безусловно, этот список не является исчерпывающим. Я уверен, что можно найти еще несколько ошибок и способов их эксплуатации. Однако если вы проверите свои сайты на наличие проблем, описанных в этой статье, и исправите их, то значительно повысите защищенность проекта.

Same Origin Policy и CSRF (cross-site request forgery)

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

Но есть запросы, которые отправляются сразу, без предварительного запроса, так называемые simple requests. Это GET, HEAD, POST с определенным Content-Type. В частности, POST-запросы с формы. Такой запрос сразу идет в контроллер. А учитывая, что куки браузер отправляет автоматически, запрос попадет в защищенный контроллер и выполнит действие на банковском сайте. Хотя ответ получить и распарсить нельзя, действие будет выполнено.

Ниже рассмотрим, как это происходит. В примере одно приложение на одном домене делает POST-запрос на другой домен, где работает второе приложение. Рассмотрим, как защититься от таких запросов с помощью CSRF-токена.

Пример жульничества

Создадим два приложения на Spring Boot:

А именно, добавим в файл hosts строку:

Приложение-мишень

Итак, пусть в нашем приложении есть контроллер и форма, с которой что-то добавляется:

Добавление

Добавление

Форма на Thymeleaf выглядит так:

В приложении задан единственный in-memory пользователь с именем user и паролем user:

Проверку CSRF-токена мы отключили выше отдельной строкой:

Это сделано для того, чтобы продемонстрировать атаку с помощью второго приложения ниже. А затем включить CSRF-токен обратно. (По умолчанию он и так включен, просто нужно не забывать добавлять его и на форму, что будет в показано самом конце).

Мошенническое приложение

Второе приложение совсем простое, оно состоит из одного view с кнопкой атаки POST (полный код тут):

Сайт жуликов

Сайт жуликов

Защита с помощью CSRF-токена

Чтобы защититься от таких запросов, нужно включить CSRF-токен, то есть убрать строку отключения, которую мы добавили выше:

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

Обычно для этого пользователь должен перейти по мошеннической ссылке (которая может быть изменена с помощью сокращателя ссылок).

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

Благодаря тому, что она авторизована на сайте банка, тот обработает запрос на перевод.

Методы GET, HEAD, OPTIONS и TRACE не подвержены CSRF, потому что предназначены только для получения информации и не изменяют состояние сервера.

Методы POST, PUT, DELETE и PATCH должны быть защищены от CSRF.

Cookies сессии

Как работает межсайтовая подделка запросов?

Для того, чтобы злоумышленник осуществил атаку CSRF, нужны определённые условия:

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

Вот пример атаки через обычную ссылку:

<a href=“вредоносная ссылка”>Unsubscribe here</a>

Или через тэг изображения:

<img src=“вредоносная ссылка” width=“0” height=“0” border=“0”>

Способы защиты от CSRF атак

Выбор защищённых фреймфорков

Anti-CSRF токены

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

Токен должен удовлетворять следующим условиям:

  • быть уникальным в пределах каждой операции;
  • использоваться один раз;
  • иметь размер устойчивый к подбору;
  • генерироваться криптографически стойким генератором псевдослучайных чисел;
  • иметь ограниченное время жизни.

Использование двух токенов

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

Использование флага Same-Site в сookies

Этот флаг помечает куки для определенного домена.

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

Этот флаг поддерживает большинство браузеров. Его стоить использовать как часть общей стратегии защиты от CSRF атак.

Требуйте подтверждения от пользователя

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

Читайте также: