- 3.1
- Версия документации: 6.1
Политика безопасности контента¶
Content Security Policy (CSP) is a web security standard that helps prevent content injection attacks by restricting the sources from which content can be loaded. It plays an important role in a comprehensive security strategy.
Инструкции по настройке в проекте Django см. в документации по использованию CSP <csp-config>. Руководство по HTTP по CSP см. в Руководстве MDN по CSP.
Обзор¶
Спецификация Content-Security-Policy <https://www.w3.org/TR/CSP3/>`_ определяет два взаимодополняющих заголовка:
Content-Security-Policy: обеспечивает соблюдение политики CSP, блокируя контент, который нарушает определенные директивы.Content-Security-Policy-Report-Only: сообщает о нарушениях CSP без блокировки контента, что позволяет проводить неинтрузивное тестирование.
Each policy is composed of one or more directives and their values, which together instruct the browser on how to handle specific types of content.
Когда ContentSecurityPolicyMiddleware включен, Django автоматически создает и прикрепляет соответствующие заголовки к каждому ответу на основе настроенных настроек, если они еще не были установлены другим уровнем.
Настройки¶
ContentSecurityPolicyMiddleware настраивается с использованием следующих параметров:
SECURE_CSP: определяет принудительную политику безопасности контента.SECURE_CSP_REPORT_ONLY: определяет Политику безопасности контента только для отчетов.
Эти настройки можно использовать независимо или вместе.
Используйте только
SECURE_CSP, чтобы применить политику, которая уже была протестирована и проверена.Используйте
SECURE_CSP_REPORT_ONLYотдельно, чтобы оценить новую политику, не нарушая работу сайта. Этот режим не блокирует нарушения, а только протоколирует их. Он полезен для тестирования и мониторинга, но не обеспечивает защиты от активных угроз.Используйте оба, чтобы поддерживать обязательный базовый уровень при экспериментировании с изменениями. Даже в случае устоявшихся политик продолжение сбора отчетов может помочь обнаружить регрессии, неожиданные изменения в поведении или потенциальное вмешательство в производственные среды.
Отчеты о нарушениях правил¶
Когда происходит нарушение CSP, браузеры обычно регистрируют подробности в консоли разработчика, обеспечивая немедленную обратную связь во время разработки. Чтобы также получать эти отчеты программным способом, политика должна включать директиву Reporting, например report-uri, которая указывает, куда следует отправлять данные о нарушениях.
Django поддерживает настройку этих директив через настройки SECURE_CSP_REPORT_ONLY, но отчеты будут создаваться браузером только в том случае, если политика явно включает действительную директиву отчетов.
Django не предоставляет встроенных функций для получения, хранения или обработки отчетов о нарушениях. Для их сбора и анализа необходимо реализовать собственную конечную точку отчетности или интегрироваться со сторонней службой мониторинга.
Константы CSP¶
Django предоставляет предопределенные константы, представляющие общие ключевые слова исходных выражений CSP, такие как «self», «none» и «unsafe-inline». Эти константы предназначены для использования в значениях директив, определенных в настройках.
Они доступны через перечисление CSP, и их рекомендуется использовать вместо необработанных строк. Это помогает избежать распространенных ошибок, таких как опечатки, неправильное цитирование или непоследовательное форматирование, а также обеспечивает соответствие спецификации CSP.
- class CSP¶
Enum предоставляет стандартизированные константы для распространенных исходных выражений CSP.
- NONE¶
Представляет
'none'. Блокирует загрузку ресурсов для данной директивы.
- REPORT_SAMPLE¶
Представляет
'образец отчета'. Предписывает браузеру включать в отчеты образец кода, нарушающего правила. Обратите внимание, что это может привести к раскрытию конфиденциальных данных.
- SELF¶
Представляет «я». Позволяет загружать ресурсы из одного и того же источника (одна и та же схема, хост и порт).
- STRICT_DYNAMIC¶
Представляет
'строго-динамический'. Позволяет выполнять скрипты, загруженные доверенным скриптом (например, с действительным nonce или хэшем), без необходимости'unsafe-inline'.
- UNSAFE_EVAL¶
Представляет unsafe-eval. Позволяет использовать
eval()и подобные функции JavaScript. Сильно обескуражен.
- UNSAFE_HASHES¶
Представляет
'unsafe-hash'. Разрешает встроенные обработчики событий и некоторые URIjavascript:, если их хэши содержимого соответствуют правилу политики. Требуется 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с безопасным случайным одноразовым номером, который генерируется для каждого запроса. Подробное объяснение см. в Использование одноразового номера.
Декораторы¶
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 CSP («число, используемое один раз») — это уникальное случайное значение, генерируемое для каждого ответа HTTP. Django поддерживает nonce как безопасный способ разрешить выполнение определенных встроенных элементов <script> или <style> без использования 'unsafe-inline'.
Одноразовые номера включаются путем включения специального заполнителя 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 }} используется во время рендеринга шаблона. Это позволяет избежать ненужной работы для страниц, которые не используют одноразовые номера.
Однако, поскольку одноразовые номера должны быть уникальными для каждого запроса, при использовании полностраничного кэширования требуется особая осторожность (например, промежуточное программное обеспечение кэша Django, кэширование CDN). Обслуживание кэшированных ответов с ранее сгенерированными одноразовыми номерами может привести к повторному использованию среди пользователей и запросов. Хотя такие ответы могут по-прежнему работать (поскольку одноразовый номер в заголовке CSP и содержимом HTML совпадают), повторное использование противоречит цели одноразового номера и ослабляет безопасность.
Чтобы гарантировать, что политики, основанные на одноразовом коде, остаются эффективными:
Избегайте кэширования полных ответов, включающих
{{ csp_nonce }}.Если кэширование необходимо, используйте стратегию, которая вводит новый одноразовый номер при каждом запросе, или рассмотрите возможность рефакторинга вашего приложения, чтобы вообще избежать встроенных сценариев и стилей.