Django CsrfViewMiddleware и эксплуатируемый поддомен

Контекст (двойная отправка файлов cookie и поддоменов):

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

При создании интерфейса, который находится в другом (поддомене), чем серверная часть, вы должны указать атрибут domain для файла cookie. Например, если интерфейс включен app.example.com, а серверная часть включена api.example.com , тогда domain для файла cookie должно быть установлено значение example.com, иначе app.example.com не сможет прочитать CSRFToken из файла cookie.

Однако это создает уязвимость для использования поддоменов. В этой презентации от OWASP объясняется, как это работает. Насколько я понимаю, поскольку мы разрешаем поддоменам example.com считывать файлы cookie, то вредоносный сайт, подобный evil.example.com, может быть настроен на ложную установку файлов cookie CSRF в обход защиты CSRF с помощью метода двойной отправки файлов cookie.

Вопрос

У Django может быть защита для этого, но я с трудом могу найти какую-либо документацию по этому поводу. В частности, в нем есть этот CSRF_TRUSTED_ORIGINS, используемый CsrfViewMiddleware. Вот что говорится в документах: CSRF_TRUSTED_ORIGINS

Список надежных источников для небезопасных запросов (например, POST).

Для запросов, содержащих заголовок Origin, защита CSRF в Django требует, чтобы заголовок соответствовал заголовку origin, присутствующему в заголовке Host.

Для безопасного небезопасного запроса, который не содержит заголовка Origin, в запросе должен быть заголовок Referer, соответствующий заголовку origin, представленному в заголовке Host.

Эти проверки предотвращают, например, успешное выполнение POST-запроса от subdomain.example.com в отношении api.example.com. Если вам нужны небезопасные запросы от разных источников, продолжая пример, добавьте 'https://subdomain.example.com' в этот список (и/или http://... если запросы исходят с небезопасной страницы).

Этот параметр также поддерживает поддомены, поэтому вы можете добавить "https://*.example.com", например, чтобы разрешить доступ со всех поддоменов example.com.

А перефразированная реализация в django.middleware выглядит следующим образом:

class CsrfViewMiddleware(MiddlewareMixin):
    def _check_referer(self, request):
       referer = request.META.get("HTTP_REFERER")
        if referer is None:
            raise RejectRequest(REASON_NO_REFERER)

        try:
            referer = urlparse(referer)
        except ValueError:
            raise RejectRequest(REASON_MALFORMED_REFERER)

        # Make sure we have a valid URL for Referer.
        if "" in (referer.scheme, referer.netloc):
            raise RejectRequest(REASON_MALFORMED_REFERER)

        # Ensure that our Referer is also secure.
        if referer.scheme != "https":
            raise RejectRequest(REASON_INSECURE_REFERER)

        if any(
            is_same_domain(referer.netloc, host)
            for host in self.csrf_trusted_origins_hosts
        ):
            # Passes _check_referer
            return

    @cached_property
    def csrf_trusted_origins_hosts(self):
        return [
            urlparse(origin).netloc.lstrip("*")
            for origin in settings.CSRF_TRUSTED_ORIGINS
        ]

Достаточно ли включения домена frontends в CSRF_TRUSTED_ORIGINS для защиты от попыток взлома с помощью поддомена?

OWASP объясняет метод "Двойной отправки файлов cookie с подписью", но это добавляет мне много дополнительных возможностей из-за того, как я настраиваю аутентификацию. В идеале я хочу просто полагаться на то, что django уже реализовал для защиты CSRF, если этого достаточно.

Вернуться на верх