Spec-Zone.ru › Django 5.1

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

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

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

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

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

  1. Файл cookie CSRF, содержащий случайное секретное значение, к которому у других сайтов нет доступа.

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

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

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

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

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

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

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

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

    Это также устраняет возможность атаки «человек посередине», возможной при использовании независимого от сеанса секрета по 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 за пределы текущего хоста или домена cookie можно сделать с помощью настройки CSRF_TRUSTED_ORIGINS.

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

Он намеренно игнорирует запросы GET (и другие запросы, определенные как «безопасные» в RFC 9110#section-9.2.1). Эти запросы никогда не должны иметь потенциально опасных побочных эффектов, поэтому атака CSRF с запросом GET должна быть безопасной. RFC 9110#section-9.2.1 определяет 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" ...>" для ссылок на сторонние сайты.

Ограничения

Поддомены на одном сайте смогут устанавливать файлы cookie для всего домена на клиенте. Установив файл cookie и используя соответствующий токен, поддомены смогут обойти защиту CSRF. Единственный способ избежать этого — убедиться, что поддомены контролируются доверенными пользователями (или, по крайней мере, не могут устанавливать файлы cookie). Обратите внимание, что даже без 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")
Изменено в Django 5.0:

Добавлена поддержка обертывания асинхронных функций представлений.

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)
Изменено в Django 5.0:

Добавлена поддержка обертывания асинхронных функций представлений.

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)
Изменено в Django 5.0:

Добавлена поддержка обертывания асинхронных функций представлений.

ensure_csrf_cookie(view)

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

Изменено в Django 5.0:

Добавлена поддержка обертывания асинхронных функций представлений.

Настройки

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

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

Некоторые инструменты аудита безопасности отмечают это как проблему, но, как уже говорилось, злоумышленник не может украсть куки 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.1/ref/csrf/

Spec-Zone.ru

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