Перейти к содержимому

Как отключить csrf проверку в django

  • автор:

Отключить csrf в Django

Необходимо отключить проверку csrf на POST запросы. Я пишу просто API на Django, к API можно получить доступ только по секретному ключу (150 знаков), и даже если есть ключ, то еще нужна авторизация, после успешной авторизации выдается access_token на время, потом нужно обновлять, так что в общем-то не вижу надобности в csrf.
Сейчас сделал что есть отдельный метод у API csrf_token который будет возвращать этот самый токен, но мне такое решение не нравится

Int64 ★★★
02.10.15 19:27:27 MSK

Защита от подделки межсайтовых запросов ¶

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

Первая защита от атак CSRF — гарантировать, что запросы GET (и другие «безопасные» методы, как определено RFC 7231 # section-4.2.1 ) не имеют побочных эффектов. Запросы через «небезопасные» методы, такие как POST, PUT и DELETE, можно защитить, выполнив следующие действия.

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

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

  1. По умолчанию промежуточное ПО CSRF активировано в MIDDLEWARE настройках. Если вы переопределите этот параметр, помните, что он ‘django.middleware.csrf.CsrfViewMiddleware’ должен быть перед любым промежуточным программным обеспечением просмотра, которое предполагает, что CSRF-атаки были устранены. Если вы отключили его, что не рекомендуется, вы можете использовать его csrf_protect() в определенных представлениях, которые хотите защитить (см. Ниже).
  2. В любом шаблоне, который использует форму POST, используйте csrf_token тег внутри элемента, если форма предназначена для внутреннего URL-адреса, например:

form method="post"> csrf_token %> 

AJAX ¶

Хотя указанный выше метод может использоваться для запросов AJAX POST, он имеет некоторые неудобства: вы должны не забывать передавать токен CSRF как данные POST с каждым запросом POST. По этой причине существует альтернативный метод: для каждого XMLHttpRequest установите настраиваемый X-CSRFToken заголовок (как указано в CSRF_HEADER_NAME настройке) на значение токена CSRF. Часто это проще, потому что многие фреймворки JavaScript предоставляют перехватчики, которые позволяют устанавливать заголовки для каждого запроса.

Во-первых, вы должны получить токен CSRF. Как это сделать, зависит от того , или нет , CSRF_USE_SESSIONS и CSRF_COOKIE_HTTPONLY включены настройки.

Получение маркеров , если CSRF_USE_SESSIONS и CSRF_COOKIE_HTTPONLY есть False ¶

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

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

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

function getCookie(name)  let cookieValue = null; if (document.cookie && document.cookie !== '')  const cookies = document.cookie.split(';'); for (let i = 0; i  cookies.length; i++)  const cookie = cookies[i].trim(); // Does this cookie string begin with the name we want? if (cookie.substring(0, name.length + 1) === (name + '='))  cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; > > > return cookieValue; > const csrftoken = getCookie('csrftoken'); 

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

const csrftoken = Cookies.get('csrftoken'); 

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

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

Получение маркера , если CSRF_USE_SESSIONS или CSRF_COOKIE_HTTPONLY является True ¶

Если вы активируете CSRF_USE_SESSIONS или CSRF_COOKIE_HTTPONLY , вы должны включить токен CSRF в свой HTML и прочитать токен из DOM с помощью JavaScript:

 csrf_token %> script> const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value; script> 
Установка токена на запрос AJAX ¶

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

const request = new Request( /* URL */, headers: 'X-CSRFToken': csrftoken>> ); fetch(request,  method: 'POST', mode: 'same-origin' // Do not send CSRF token to another domain. >).then(function(response)  // . >); 

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

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

form method="post"> <csrf_input >> 

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

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

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

Декоратор, обеспечивающий защиту CsrfViewMiddleware вида.

from django.shortcuts import render from django.views.decorators.csrf import csrf_protect @csrf_protect def my_view(request): c = <> # . return render(request, "a_template.html", c) 

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

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

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

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

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

Как это работает ¶

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

  1. Файл cookie CSRF, основанный на случайном секретном значении, к которому другие сайты не будут иметь доступа. Этот файл cookie установлен CsrfViewMiddleware . Он отправляется с каждым вызванным ответом django.middleware.csrf.get_token() (функция, используемая внутри для получения токена CSRF), если он еще не был установлен в запросе. Для защиты от атак BREACH токен — это не просто секрет; к секрету добавляется случайная маска, которая используется для его шифрования. По соображениям безопасности значение секрета изменяется каждый раз, когда пользователь входит в систему.
  2. Скрытое поле формы с именем csrfmiddlewaretoken, присутствующее во всех исходящих формах POST. Значение этого поля, опять же, является значением секрета с маской, которая добавляется к нему и используется для его шифрования. Маска восстанавливается при каждом вызове, get_token() так что значение поля формы изменяется в каждом таком ответе. Эта часть выполняется тегом шаблона.
  3. Для всех входящих запросов, которые не используют HTTP GET, HEAD, OPTIONS или TRACE, должен присутствовать файл cookie CSRF, а поле csrfmiddlewaretoken должно присутствовать и быть правильным. В противном случае пользователь получит ошибку 403. При проверке значения поля csrfmiddlewaretoken только секрет, а не полный токен, сравнивается с секретом в значении файла cookie. Это позволяет использовать постоянно меняющиеся токены. Хотя каждый запрос может использовать свой собственный токен, секрет остается общим для всех. Эта проверка выполняется CsrfViewMiddleware .
  4. Кроме того, для запросов HTTPS строгая проверка ссылки выполняется с помощью CsrfViewMiddleware . Это означает, что даже если поддомен может устанавливать или изменять файлы cookie в вашем домене, он не может заставить пользователя публиковать сообщения в вашем приложении, поскольку этот запрос не будет поступать из вашего собственного домена. Это также относится к атаке «человек посередине», которая возможна при использовании HTTPS при использовании секрета, не зависящего от сеанса, из-за того, что HTTP- Set-Cookie заголовки (к сожалению) принимаются клиентами, даже когда они общаются с сайтом по HTTPS. (Проверка ссылок не выполняется для HTTP-запросов, потому что наличие Referer заголовка недостаточно надежно для HTTP.) Если CSRF_COOKIE_DOMAIN параметр установлен, референт сравнивается с ним. Вы можете разрешить запросы между субдоменами, добавив точку в начале. Например, разрешит запросы POST от и . Если параметр не установлен, то ссылка должна соответствовать заголовку HTTP . CSRF_COOKIE_DOMAIN = ‘.example.com’ www.example.com api.example.com Host Расширение допустимых рефереров за пределы текущего хоста или домена cookie можно выполнить с помощью этой CSRF_TRUSTED_ORIGINS настройки.

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

Он намеренно игнорирует запросы GET (и другие запросы, которые определены как «безопасные» RFC 7231 # раздел-4.2.1 ). Эти запросы никогда не должны иметь потенциально опасных побочных эффектов, поэтому CSRF-атака с запросом GET должна быть безвредной. RFC 7231 # section-4.2.1 определяет POST, PUT и DELETE как «небезопасные», и все другие методы также считаются небезопасными для максимальной защиты.

Защита CSRF не может защитить от атак типа «злоумышленник в середине», поэтому используйте HTTPS с HTTP Strict Transport Security . Он также предполагает проверку заголовка HOST и отсутствие на вашем сайте каких — либо уязвимостей межсайтового скриптинга (поскольку уязвимости XSS уже позволяют злоумышленнику делать все, что позволяет уязвимость CSRF, и намного хуже).

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

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

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

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

from django.views.decorators.cache import cache_page from django.views.decorators.csrf import csrf_protect @cache_page(60 * 15) @csrf_protect def my_view(request): . 

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

Тестирование ¶

CsrfViewMiddleware Обычно будет большой помехой для тестирования функции представления , в связи с необходимостью для CSRF токена , который должен быть отправлен с каждым запросом POST. По этой причине HTTP-клиент Django для тестов был изменен, чтобы установить флаг для запросов, который ослабляет промежуточное программное обеспечение и csrf_protect декоратор, чтобы они больше не отклоняли запросы. Во всем остальном (например, отправка файлов cookie и т. Д.) Они ведут себя одинаково.

Если по какой-то причине вы хотите, чтобы тестовый клиент выполнял проверки CSRF, вы можете создать экземпляр тестового клиента, который выполняет проверки CSRF:

>>> from django.test import Client >>> csrf_client = Client(enforce_csrf_checks=True) 

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

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

Пограничные случаи ¶

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

Утилиты ¶

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

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

from django.http import HttpResponse from django.views.decorators.csrf import csrf_exempt @csrf_exempt def my_view(request): return HttpResponse('Hello world') 

requires_csrf_token ( просмотр ) ¶

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

from django.shortcuts import render from django.views.decorators.csrf import requires_csrf_token @requires_csrf_token def my_view(request): c = <> # . return render(request, "a_template.html", c) 

ensure_csrf_cookie ( просмотр ) ¶

Этот декоратор заставляет представление отправлять файл 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 должен быть самым внутренним декоратором).

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

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

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

from django.views.decorators.csrf import csrf_exempt, csrf_protect @csrf_exempt def my_view(request): @csrf_protect def protected_path(request): do_something() if some_condition(): return protected_path(request) else: do_something_else() 
Страница использует AJAX без HTML-формы ¶

Страница выполняет запрос POST через AJAX, и на странице нет HTML-формы с, csrf_token которая могла бы вызвать отправку необходимого файла cookie CSRF.

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

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

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

Настройки ¶

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

  • CSRF_COOKIE_AGE
  • CSRF_COOKIE_DOMAIN
  • CSRF_COOKIE_HTTPONLY
  • CSRF_COOKIE_NAME
  • CSRF_COOKIE_PATH
  • CSRF_COOKIE_SAMESITE
  • CSRF_COOKIE_SECURE
  • CSRF_FAILURE_VIEW
  • CSRF_HEADER_NAME
  • CSRF_TRUSTED_ORIGINS
  • CSRF_USE_SESSIONS

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

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

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

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

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

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

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

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

По соображениям безопасности токены CSRF меняются каждый раз, когда пользователь входит в систему. Любая страница с формой, созданной до входа в систему, будет иметь старый, недопустимый токен CSRF, и ее необходимо будет перезагрузить. Это может произойти, если пользователь нажмет кнопку «Назад» после входа в систему или войдет в другую вкладку браузера.

Защита от «подделки межсайтовых запросов» (CSRF) ¶

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

Первая линия защиты от атак CSRF — гарантировать, что запросы GET (и другие «безопасные» методы, как определено RFC 7231 # section-4.2.1 ) не имеют побочных эффектов. Вызовы «небезопасными» методами, такими как POST, PUT и DELETE, затем можно защитить, выполнив следующие действия.

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

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

  1. По умолчанию промежуточное ПО CSRF включено в настройках MIDDLEWARE . Если вы переопределите этот параметр, помните, что это ‘django.middleware.csrf.CsrfViewMiddleware’ должно происходить до того, как промежуточное ПО, которое полагается на CSRF-атаки, уже было отражено. Если вы отключите его, что не рекомендуется, вы можете использовать его csrf_protect() в некоторых представлениях, которые хотите защитить (см. Ниже).
  2. В любом шаблоне, который использует форму POST, используйте тег шаблона csrf_token внутри тега HTML, если форма ссылается на внутренний URL-адрес, например:

form method="post"> csrf_token %> 

AJAX ¶

Несмотря на то, что вышеуказанный метод может использоваться для запросов AJAX POST, у него есть несколько недостатков: не забудьте передать токен CSRF вместе с данными POST в каждом запросе POST. По этой причине существует другой метод: для каждого XMLHttpRequest определите элемент заголовка X-CSRFToken (как указано в настройке CSRF_HEADER_NAME ) с тем же значением, что и токен CSRF. Часто это проще, потому что многие библиотеки JavaScript предоставляют точки расширения, которые позволяют добавлять элементы заголовка для каждого запроса.

Сначала необходимо получить токен CSRF. Способ сделать это зависит от того CSRF_USE_SESSIONS , включены ли настройки и CSRF_COOKIE_HTTPONLY .

Приобретение если CSRF_USE_SESSIONS и CSRF_COOKIE_HTTPONLY стоит знак False ¶

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

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

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

function getCookie(name)  let cookieValue = null; if (document.cookie && document.cookie !== '')  const cookies = document.cookie.split(';'); for (let i = 0; i  cookies.length; i++)  const cookie = cookies[i].trim(); // Does this cookie string begin with the name we want? if (cookie.substring(0, name.length + 1) === (name + '='))  cookieValue = decodeURIComponent(cookie.substring(name.length + 1)); break; > > > return cookieValue; > const csrftoken = getCookie('csrftoken'); 

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

const csrftoken = Cookies.get('csrftoken'); 

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

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

Приобретение токена, если CSRF_USE_SESSIONS или CSRF_COOKIE_HTTPONLY стоит True ¶

Если вы включили CSRF_USE_SESSIONS или CSRF_COOKIE_HTTPONLY , вы должны включить токен CSRF в HTML-код и прочитать токен в DOM в JavaScript:

 csrf_token %> script> const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value; script> 
Установка токена для запроса AJAX ¶

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

const request = new Request( /* URL */, headers: 'X-CSRFToken': csrftoken>> ); fetch(request,  method: 'POST', mode: 'same-origin' // Do not send CSRF token to another domain. >).then(function(response)  // . >); 

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

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

form method="post"> <csrf_input >> 

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

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

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

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

from django.shortcuts import render from django.views.decorators.csrf import csrf_protect @csrf_protect def my_view(request): c = <> # . return render(request, "a_template.html", c) 

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

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

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

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

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

Операция ¶

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

  1. Файл cookie CSRF, основанный на случайном секретном значении, к которому другие сайты не будут иметь доступа. Этот файл cookie создается промежуточным программным обеспечением CsrfViewMiddleware . Он отправляется с каждым вызванным ответом django.middleware.csrf.get_token() (функция, используемая внутри для получения токена CSRF), если он еще не был определен для запроса. Для защиты от атак BREACH токен — это не просто секрет; к секрету добавляется случайная маска, которая используется для его шифрования. По соображениям безопасности секретное значение изменяется каждый раз, когда пользователь входит в систему.
  2. Скрытое поле формы с именем «csrfmiddlewaretoken» присутствует во всех исходящих формах POST. Значение этого поля, опять же, является значением секрета с маской, которая добавляется к нему и используется для его шифрования. Маска регенерируется при каждом вызове, get_token() поэтому значение поля формы изменяется в каждом таком ответе. Это действие выполняется тегом шаблона.
  3. Для всех входящих запросов, которые не используют методы HTTP GET, HEAD, OPTIONS или TRACE, должен присутствовать файл cookie CSRF, а поле «csrfmiddlewaretoken» должно присутствовать и быть правильным. В противном случае пользователь получит ошибку 403. При проверке значения поля csrfmiddlewaretoken только секретное значение, а не полный токен, сравнивается с секретным значением содержимого cookie. Это позволяет использовать постоянно меняющиеся токены. Хотя каждый запрос может использовать свой токен, секретное значение остается общим для всех. Эта проверка выполняется промежуточным программным обеспечением CsrfViewMiddleware .
  4. Кроме того, для запросов HTTPS строгий контроль реферера выполняется CsrfViewMiddleware . Это означает, что даже если субдомен может устанавливать или изменять файлы cookie для вашего домена, он не может заставить пользователя отправлять данные в ваше приложение, потому что этот запрос не будет исходить из вашего точного домена. Это также защищает от атаки «Man-In-The-Middle», которая возможна по протоколу HTTPS при использовании независимого от сеанса секретного значения, поскольку заголовки HTTP Set-Cookie (к сожалению) принимаются клиенты, даже когда они общаются с сайтом по HTTPS. (Проверка реферера не выполняется для HTTP-запросов, потому что наличие заголовка Referer недостаточно надежно для HTTP.) Если настройка CSRF_COOKIE_DOMAIN определена, референт сравнивается с ней. Этот параметр учитывает поддомены. Например, разрешите POST-запросы от и . Если параметр не определен, реферер должен соответствовать заголовку HTTP . CSRF_COOKIE_DOMAIN = ‘.exemple.com’ www.exemple.com api.exemple.com Host Расширение принятых рефереров за пределы текущего хоста или домена cookie можно выполнить с помощью этой настройки CSRF_TRUSTED_ORIGINS .

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

Запросы GET намеренно игнорируются (как и другие запросы, определенные как «безопасные» RFC 7231 # раздел-4.2.1 ). Эти запросы никогда не должны иметь потенциально опасных побочных эффектов, и в этом случае CSRF-атака с запросом GET должна быть безвредной. RFC 7231 # section-4.2.1 определяет методы POST, PUT и DELETE как «небезопасные», и все другие методы также считаются небезопасными для максимальной защиты.

Защита CRSF не может защитить от атак «злоумышленник посередине», поэтому HTTPS следует использовать со строгой безопасностью транспорта HTTP (HSTS) . Также предполагается, что заголовок HOST был проверен и что на сайте нет уязвимостей межсайтового скриптинга (поскольку этот тип уязвимости уже позволяет злоумышленнику делать то, что делает уязвимость CSRF, и больше).

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

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

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

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

from django.views.decorators.cache import cache_page from django.views.decorators.csrf import csrf_protect @cache_page(60 * 15) @csrf_protect def my_view(request): . 

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

Тесты ¶

Обычно CsrfViewMiddleware затрудняет тестирование функций просмотра, потому что токен CSRF должен отправляться с каждым запросом POST. Таким образом, HTTP-клиент Django, используемый для тестирования, был изменен для автоматической пометки запросов и, таким образом, информирования промежуточного программного обеспечения и декоратора, csrf_protect чтобы они не отклоняли эти запросы. Во всем остальном (например, отправка файлов cookie и т. Д.) Поведение во время тестирования такое же.

Если по какой-то причине вы хотите, чтобы HTTP-клиент, используемый для тестирования, выполнял проверки CSRF, вы можете создать экземпляр тестового клиента, который применяет проверки CSRF:

>>> from django.test import Client >>> csrf_client = Client(enforce_csrf_checks=True) 

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

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

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

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

Утилиты ¶

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

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

from django.http import HttpResponse from django.views.decorators.csrf import csrf_exempt @csrf_exempt def my_view(request): return HttpResponse('Hello world') 

requires_csrf_token ( просмотр ) ¶

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

from django.shortcuts import render from django.views.decorators.csrf import requires_csrf_token @requires_csrf_token def my_view(request): c = <> # . return render(request, "a_template.html", c) 

ensure_csrf_cookie ( просмотр ) ¶

Этот декоратор заставляет представление отправлять файл 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() частности, для пути, который необходимо защитить. Пример:

from django.views.decorators.csrf import csrf_exempt, csrf_protect @csrf_exempt def my_view(request): @csrf_protect def protected_path(request): do_something() if some_condition(): return protected_path(request) else: do_something_else() 
Страница использует AJAX без HTML-формы ¶

Страница выполняет запрос POST через AJAX, и на этой странице нет HTML-формы с тегом, csrf_token который мог бы вызвать отправку файла cookie CSRF.

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

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

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

Настройки ¶

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

  • CSRF_COOKIE_AGE
  • CSRF_COOKIE_DOMAIN
  • CSRF_COOKIE_HTTPONLY
  • CSRF_COOKIE_NAME
  • CSRF_COOKIE_PATH
  • CSRF_COOKIE_SAMESITE
  • CSRF_COOKIE_SECURE
  • CSRF_FAILURE_VIEW
  • CSRF_HEADER_NAME
  • CSRF_TRUSTED_ORIGINS
  • CSRF_USE_SESSIONS

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

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

Нет, сознательно нет. Без атаки «человек посередине» у злоумышленника нет возможности отправить файл cookie с токеном CSRF в браузер своей жертвы; Успешная атака должна иметь возможность получить cookie из браузера жертвы через XSS или другие подобные средства, и в этом случае злоумышленнику обычно не нужно атаковать через CSRF.

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

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

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

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

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

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

Отключить CSRF для одного POST-запроса?

Есть некий АПИ-запрос, на который делает запрос некий сторонний сайт с некими параметрами, и после этого мне нужно сделать редирект на определенную страницу своего сайта.

from rest_framework.generics import GenericAPIView from serializers import AddSomethingSerializer class AddingSomething(GenericAPIView): permission_classes = (permissions.AllowAny, ) serializer_class = AddSomethingSerializer queryset = None def post(self, request, **kwargs): # .. Some magic .. return HttpResponseRedirect(redirect_to=reverse('something_added'))

Все хорошо, но при редиректе со стороннего сайта возникает исключение:

"detail": "CSRF Failed: CSRF token missing or incorrect."

Как мне отключить проверку CSRF только для данного АПИ, а для других АПИ оставить в силе?

@method_decorator(csrf_exempt) def post(self, request, **kwargs)
@method_decorator(csrf_exempt, name='dispatch') class AddingSomething(GenericAPIView):
from django.views.decorators.csrf import csrf_exempt from views import AddingSomething urlpatterns = [ url('^add_something/$', csrf_exempt(AddingSomething.as_view()), name='api-add-something'), . 

Вариант отключить полностью в authentication_classes — не подходит

  • Вопрос задан более трёх лет назад
  • 2845 просмотров

3 комментария

Простой 3 комментария

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *