HTTP headers / XSS

CSP для Nginx, Apache, WordPress и 1С‑Битрикс: внедрение без поломки сайта

Строим политику по реальным ресурсам, сначала собираем отчёты, затем удаляем unsafe-inline и только после этого включаем блокировку.

Проверено
25 августа 2026
Чтение
≈ 18 минут
Уровень
Разработчик + администратор

Модель

Что CSP делает и чего от неё не ждать

CSP сообщает браузеру, откуда разрешено загружать и выполнять ресурсы. Строгая политика снижает последствия XSS, ограничивает встраивание страницы и помогает контролировать небезопасные загрузки.

Она не исправляет уязвимый серверный код, нарушение прав доступа или SQL‑инъекцию. CSP — дополнительный рубеж. Если политика разрешает 'unsafe-inline', * и все внешние домены, она может выглядеть внушительно, но слабо ограничивать атаку.

Перед настройкой инвентаризируйте script, style, font, img, connect, frame, worker и form‑action. Удалите неизвестные зависимости — каждое исключение расширяет доверенную поверхность.

Этап 1

Начните с Report-Only и собирайте полезные отчёты

Content-Security-Policy-Report-Only: default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'; form-action 'self'; report-uri /csp-report

Report-Only не блокирует ресурсы, но позволяет увидеть нарушения. Ограничьте размер тела и частоту endpoint, не записывайте секреты из отчётов, фильтруйте шум от расширений браузера. report-to развивается, но для совместимости часто оставляют и report-uri.

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

Этап 2

Перейдите от списка доменов к nonce или hash

Современная строгая CSP выдаёт случайный nonce на каждый ответ и добавляет его разрешённым script. Статические inline‑фрагменты можно разрешить хешем. Не используйте постоянный nonce и не вставляйте в разрешённый блок непроверенные данные.

Content-Security-Policy: default-src 'self'; script-src 'nonce-{RANDOM}' 'strict-dynamic'; object-src 'none'; base-uri 'none'; frame-ancestors 'none'; form-action 'self'; upgrade-insecure-requests

Это каркас, а не готовая строка для копирования. Добавьте отдельные img-src, style-src, font-src, connect-src, frame-src и worker-src по фактической архитектуре. Проверяйте поддержку целевых браузеров.

Конфигурация

Nginx и Apache: заголовок должен приходить на все HTML-ответы

Nginx

add_header Content-Security-Policy-Report-Only "default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'; form-action 'self'; report-uri /csp-report" always;

Apache 2.4

<IfModule mod_headers.c>
  Header always set Content-Security-Policy-Report-Only "default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'; form-action 'self'; report-uri /csp-report"
</IfModule>

Проверьте итоговый ответ через DevTools или curl -I. Заголовок может дублироваться на CDN и origin: несколько CSP применяются одновременно, то есть итог становится строже, а диагностика — сложнее. Назначьте один источник истины.

CMS

WordPress и Битрикс требуют работы с inline-кодом

CMS, плагины и визуальные редакторы часто генерируют inline‑script, inline‑style и обработчики onclick. Временное 'unsafe-inline' помогает миграции, но не должно становиться финальной целью.

  1. Соберите нарушения по публичным шаблонам и админке отдельно.
  2. Удалите плагины и виджеты без владельца.
  3. Вынесите свой inline‑код во внешние файлы.
  4. Там, где код генерируется сервером, добавляйте nonce через контролируемый слой рендера.
  5. Для стилей создайте отдельный план: CSS‑in‑JS и style‑атрибуты требуют переработки.
  6. Включайте enforcement сначала на небольшом наборе страниц с быстрым откатом.

Политика из генератора может заблокировать оплату, капчу, AJAX, редактор, карту или WebSocket. Сначала Report‑Only, полноценные сценарии и мониторинг.

Приёмка

Как понять, что CSP реально защищает

  • Нет * и схемы https: в script-src без необходимости.
  • Нет постоянного 'unsafe-inline' и 'unsafe-eval' в script-src.
  • Заданы object-src, base-uri, frame-ancestors и form-action.
  • Nonce уникален для каждого ответа и не попадает в пользовательские данные.
  • Отчёты очищены от ложных срабатываний, критичные нарушения создают алерт.
  • Политика проверена в публичной части, кабинете, оплате и админке.

Включайте блокировку поэтапно и сохраняйте быстрый способ вернуть Report‑Only. Хорошая CSP короткая, понятная и сопровождается владельцем.

FAQ

Частые вопросы

Можно настроить CSP через meta-тег?

Часть возможностей доступна, но HTTP-заголовок полнее и применяется раньше. Например, frame-ancestors не поддерживается в meta. Предпочитайте заголовок ответа.

Нужно ли одновременно использовать X-Frame-Options?

frame-ancestors — современный контроль встраивания. X-Frame-Options иногда сохраняют для старых клиентов, но значения должны не конфликтовать.

Почему две CSP ломают сайт?

Несколько политик не объединяют разрешения; браузер соблюдает каждую, поэтому действует пересечение ограничений.

CSP заменяет экранирование HTML?

Нет. Контекстное экранирование, безопасные DOM API и валидация остаются обязательными. CSP ограничивает последствия части ошибок.

Первоисточники

Документы и руководства

  1. MDN: Content Security Policy — директивы и стратегии внедрения
  2. Apache HTTP Server: mod_headers — директива Header always set
  3. Nginx: ngx_http_headers_module — директива add_header
  4. OWASP CSP Cheat Sheet — nonce, hash и anti-patterns

Дата проверки: 25 августа 2026. Нормы, ставки, интерфейсы ведомств и условия сервисов могут измениться. Перед юридически или финансово значимым решением сверьте актуальную редакцию первоисточника и обстоятельства вашей организации.

Напиши нам