Spec-Zone.ru › Django 6.0

Политика безопасности содержимого

Добавлено в Django 6.0.

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

Инструкции по настройке в проекте Django см. в документации «Использование CSP». Руководство по CSP для HTTP см. в руководстве MDN по CSP.

Обзор

Спецификация Content-Security-Policy определяет два взаимодополняющих заголовка:

  • Content-Security-Policy: обеспечивает соблюдение политики CSP, блокируя содержимое, нарушающее заданные директивы.
  • Content-Security-Policy-Report-Only: сообщает о нарушениях CSP, не блокируя содержимое, что позволяет проводить тестирование без вмешательства в работу сайта.

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

Когда включён ContentSecurityPolicyMiddleware, Django автоматически формирует и добавляет к каждому ответу соответствующие заголовки на основе настроенных параметров, если они ещё не заданы на другом уровне.

Параметры

ContentSecurityPolicyMiddleware настраивается с помощью следующих параметров:

  • SECURE_CSP: задаёт применяемую политику безопасности содержимого.
  • SECURE_CSP_REPORT_ONLY: задаёт политику безопасности содержимого только для отчётов.

Эти параметры можно использовать отдельно или вместе

  • Используйте только SECURE_CSP, чтобы применять политику, которая уже прошла тестирование и проверку.
  • Используйте отдельно SECURE_CSP_REPORT_ONLY, чтобы оценить новую политику, не нарушая работу сайта. В этом режиме нарушения не блокируются, а только регистрируются. Это удобно для тестирования и мониторинга, но не обеспечивает защиту от активных угроз.
  • Используйте оба параметра, чтобы сохранять действующую базовую политику и одновременно экспериментировать с изменениями. Даже для хорошо отлаженных политик сбор отчётов помогает выявлять регрессии, неожиданные изменения поведения или возможное вмешательство в рабочей среде.

Отчёты о нарушениях политики

При нарушении CSP браузеры обычно записывают подробную информацию в консоль разработчика, обеспечивая оперативную обратную связь во время разработки. Чтобы также получать эти отчёты программно, политика должна содержать директиву для отправки отчётов, например report-uri, которая задаёт адрес для отправки данных о нарушениях.

Django поддерживает настройку этих директив через параметры SECURE_CSP_REPORT_ONLY, однако браузер будет отправлять отчёты, только если политика явно содержит допустимую директиву для отправки отчётов.

Django не предоставляет встроенных средств для получения, хранения или обработки отчётов о нарушениях. Чтобы собирать и анализировать их, необходимо реализовать собственную конечную точку для отчётов или интегрировать стороннюю службу мониторинга.

Константы CSP

Django предоставляет предопределённые константы для распространённых ключевых слов выражений источников CSP, таких как 'self', 'none' и 'unsafe-inline'. Эти константы предназначены для использования в значениях директив, заданных в параметрах.

Они доступны через перечисление CSP; рекомендуется использовать их вместо обычных строк. Это помогает избежать распространённых ошибок, таких как опечатки, неправильное заключение в кавычки или несогласованное форматирование, и обеспечивает соответствие спецификации CSP.

class CSP [исходный код]

Перечисление со стандартными константами для распространённых выражений источников CSP.

NONE

Представляет 'none'. Блокирует загрузку ресурсов для заданной директивы.

REPORT_SAMPLE

Представляет 'report-sample'. Указывает браузеру включать в отчёты фрагмент кода, вызвавшего нарушение. Обратите внимание, что это может привести к раскрытию конфиденциальных данных.

SELF

Представляет 'self'. Разрешает загрузку ресурсов с того же источника (с той же схемой, узлом и портом).

STRICT_DYNAMIC

Представляет 'strict-dynamic'. Разрешает выполнение скриптов, загруженных доверенным скриптом (например, скриптом с допустимым nonce или хешем), без необходимости использовать 'unsafe-inline'.

UNSAFE_EVAL

Представляет 'unsafe-eval'. Разрешает использование eval() и подобных функций JavaScript. Настоятельно не рекомендуется.

UNSAFE_HASHES

Представляет 'unsafe-hashes'. Разрешает встроенные обработчики событий и некоторые URI javascript:, если их содержимое соответствует хешу правила политики. Требуется CSP уровня 3 или выше.

UNSAFE_INLINE

Представляет 'unsafe-inline'. Разрешает выполнение встроенных скриптов, стилей и URL-адресов javascript:. В целом не рекомендуется, особенно для скриптов.

WASM_UNSAFE_EVAL

Представляет 'wasm-unsafe-eval'. Разрешает компиляцию и выполнение кода WebAssembly без включения 'unsafe-eval' для скриптов.

NONCE

Специальное для Django значение-заполнитель ("<CSP_NONCE_SENTINEL>"), используемое в директивах script-src или style-src для включения CSP на основе nonce. Во время выполнения эта строка заменяется ContentSecurityPolicyMiddleware на безопасный случайный nonce, генерируемый для каждого запроса. Подробное объяснение см. в разделе Использование nonce.

Декораторы

Django предоставляет декораторы для управления заголовками политики безопасности содержимого отдельно для каждого представления. С их помощью можно переопределять или отключать применяемую политику либо политику только для отчётов для отдельных представлений, обеспечивая точную настройку в случаях, когда глобальных параметров недостаточно. При применении этих переопределений базовая CSP полностью заменяется: правила не объединяются с существующими. Их можно использовать вместе с константами, определёнными в CSP.

Предупреждение

Ослабление или отключение политики CSP на любой странице может поставить под угрозу безопасность всего сайта. Из-за политики «одного источника» злоумышленник может воспользоваться уязвимостью на одной странице, чтобы получить доступ к другим частям сайта.

csp_override(config)(view) [исходный код]

Переопределяет заголовок Content-Security-Policy для декорированного представления, используя директивы в том же формате, что и параметр SECURE_CSP.

Аргумент config должен быть отображением с нужными директивами CSP. Если config — пустое отображение ({}), в ответ, возвращаемый этим представлением, не будет добавлен заголовок для обеспечения CSP, что фактически отключит CSP для этого представления.

Примеры:

from django.http import HttpResponse
from django.utils.csp import CSP
from django.views.decorators.csp import csp_override


@csp_override(
    {
        "default-src": [CSP.SELF],
        "img-src": [CSP.SELF, "data:"],
    }
)
def my_view(request):
    return HttpResponse("Custom Content-Security-Policy header applied")


@csp_override({})
def my_other_view(request):
    return HttpResponse("No Content-Security-Policy header added")
csp_report_only_override(config)(view) [исходный код]

Переопределяет заголовок Content-Security-Policy-Report-Only для декорированного представления, используя директивы в том же формате, что и параметр SECURE_CSP_REPORT_ONLY.

Как и в случае с csp_override(), аргумент config должен быть отображением с нужными директивами CSP. Если config — пустое отображение ({}), в ответ, возвращаемый этим представлением, не будет добавлен заголовок CSP только для отчётов, что фактически отключит CSP только для отчётов для этого представления.

Примеры:

from django.http import HttpResponse
from django.utils.csp import CSP
from django.views.decorators.csp import csp_report_only_override


@csp_report_only_override(
    {
        "default-src": [CSP.SELF],
        "img-src": [CSP.SELF, "data:"],
        "report-uri": "https://mysite.com/csp-report/",
    }
)
def my_view(request):
    return HttpResponse("Custom Content-Security-Policy-Report-Only header applied")


@csp_report_only_override({})
def my_other_view(request):
    return HttpResponse("No Content-Security-Policy-Report-Only header added")

В примерах выше предполагаются представления на основе функций. Информацию о представлениях на основе классов см. в руководстве по декорированию представлений на основе классов.

Использование nonce

Nonce CSP («число, используемое один раз») — это уникальное случайное значение, генерируемое для каждого HTTP-ответа. Django поддерживает nonce как безопасный способ разрешить выполнение определённых встроенных элементов <script> или <style> без использования 'unsafe-inline'.

Чтобы включить nonce, добавьте специальный заполнитель NONCE в соответствующую директиву или директивы ваших параметров CSP, например script-src или style-src. Если он присутствует, ContentSecurityPolicyMiddleware сгенерирует nonce и добавит соответствующее выражение источника nonce-<value> в заголовок CSP.

Чтобы использовать этот nonce в шаблонах, необходимо включить контекстный процессор csp(). Он добавляет в контекст шаблона переменную csp_nonce, позволяя встроенным элементам указывать соответствующий атрибут nonce={{ csp_nonce }} во встроенных скриптах или стилях.

Браузер выполнит только те встроенные элементы, которые содержат атрибут nonce=<value> со значением, совпадающим с указанным в заголовке Content-Security-Policy (или Content-Security-Policy-Report-Only). Этот механизм позволяет точно контролировать, какой встроенный код может выполняться.

Если шаблон содержит {{ csp_nonce }}, но политика не включает NONCE, в HTML будет атрибут nonce, но в заголовке не будет необходимого выражения источника. В этом случае браузер заблокирует встроенный скрипт или стиль (либо сообщит о нём, если настроен режим только для отчётов).

Генерация nonce и кэширование

Генерация nonce в Django выполняется лениво: промежуточный слой генерирует nonce, только если во время рендеринга шаблона используется {{ csp_nonce }}. Это позволяет избежать ненужной работы для страниц, которым nonce не требуется.

Однако, поскольку nonce должен быть уникальным для каждого запроса, при использовании полноэкранного кэширования (например, промежуточного слоя кэширования Django или кэширования CDN) требуется особая осторожность. При выдаче кэшированных ответов с ранее сгенерированными nonce они могут повторно использоваться для разных пользователей и запросов. Такие ответы могут продолжать работать (поскольку nonce в заголовке CSP и HTML совпадают), однако повторное использование лишает nonce смысла и ослабляет защиту.

Чтобы политики на основе nonce оставались эффективными:

  • Не кэшируйте целые ответы, содержащие {{ csp_nonce }}.
  • Если кэширование необходимо, используйте стратегию, которая добавляет новый nonce при каждом запросе, либо рассмотрите возможность переработать приложение так, чтобы полностью отказаться от встроенных скриптов и стилей.

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

Spec-Zone.ru

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