Spec-Zone.ru › Django 5.2

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

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

Первая защита от атак CSRF заключается в обеспечении того, чтобы запросы GET (и другие «безопасные» методы, как определено в Разделе 9.2.1 RFC 9110) не имели побочных эффектов. Запросы через «опасные» методы, такие как POST, PUT и DELETE, могут затем защищаться путем выполнения шагов, изложенных в Использование защиты Django от CSRF.

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

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

  1. Куки CSRF, который представляет собой случайное секретное значение, к которому другие сайты не имеют доступа.

    CsrfViewMiddleware отправляет эти куки вместе с ответом всякий раз, когда django.middleware.csrf.get_token() вызывается. Он также может отправлять их в других случаях. По соображениям безопасности значение секрета изменяется каждый раз при входе пользователя в систему.

  2. Скрытое поле формы с именем «csrfmiddlewaretoken», присутствующее во всех исходящих формах POST.

    Чтобы защититься от атак BREACH, значение этого поля не просто секрет. Оно зашифровывается по-разному с каждым ответом с использованием маски. Маска генерируется случайным образом при каждом вызове get_token(), поэтому значение поля формы различается каждый раз.

    Эта часть выполняется тегом шаблона csrf_token.

  3. Для всех входящих запросов, не использующих HTTP GET, HEAD, OPTIONS или TRACE, должен быть присутствующим и правильным куки CSRF, а также поле «csrfmiddlewaretoken». Если это не так, пользователю будет возвращена ошибка 403.

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

    Эта проверка выполняется CsrfViewMiddleware.

  4. CsrfViewMiddleware проверяет заголовок Origin, если он предоставлен браузером, по отношению к текущему хосту и настройке CSRF_TRUSTED_ORIGINS. Это обеспечивает защиту от межподдоменных атак.
  5. Кроме того, для запросов HTTPS, если заголовок Origin не предоставлен, CsrfViewMiddleware выполняет строгую проверку referer. Это означает, что даже если поддомен может устанавливать или изменять куки на вашем домене, он не может заставить пользователя отправить POST-запрос на ваше приложение, поскольку этот запрос не будет исходить с вашего точного домена.

    Это также решает проблему атаки «человек посередине», возможной при использовании независимого от сеанса секрета под HTTPS, из-за того, что заголовки HTTP Set-Cookie (к сожалению) принимаются клиентами даже в том случае, когда они взаимодействуют со сайтом под HTTPS. (Проверка referer не выполняется для запросов HTTP, поскольку наличие заголовка Referer недостаточно надёжно в HTTP.)

    Если настройка CSRF_COOKIE_DOMAIN установлена, referer сравнивается с ней. Вы можете разрешить запросы с разных поддоменов, добавив префикс точкой. Например, CSRF_COOKIE_DOMAIN = '.example.com' позволит POST-запросам с www.example.com и api.example.com. Если настройка не установлена, то referer должен совпадать с заголовком HTTP Host.

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

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

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

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

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

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

Ограничения

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

Утилиты

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

csrf_exempt(view) [source]

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

from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt


@csrf_exempt
def my_view(request):
    return HttpResponse("Hello world")
csrf_protect(view)

Декоратор, предоставляющий защиту 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)
requires_csrf_token(view)

Обычно тег шаблона 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(view)

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

Настройки

Несколько настроек могут использоваться для управления поведением 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 и т. д. не является уязвимостью.

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

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

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

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

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

© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/5.2/ref/csrf/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API