Content Security Policy (CSP) — полное руководство по настройке
Content Security Policy (CSP) — это заголовок безопасности, который указывает браузеру, откуда разрешено загружать ресурсы: скрипты, стили, изображения, шрифты, фреймы и другие. CSP — один из самых мощных инструментов защиты от XSS-атак (Cross-Site Scripting), инъекций кода и clickjacking.
Зачем нужен CSP
XSS остаётся одной из самых распространённых веб-уязвимостей по версии OWASP Top 10. Даже при тщательной фильтрации пользовательского ввода существует риск пропустить вектор атаки. CSP работает как последний рубеж обороны: даже если злоумышленник внедрит вредоносный код, браузер не выполнит его, если источник не разрешён в политике.
Что защищает CSP:
- XSS-атаки — блокирует выполнение inline-скриптов и загрузку скриптов с неавторизованных доменов
- Data injection — предотвращает загрузку контента из неожиданных источников
- Clickjacking — директива frame-ancestors контролирует, кто может встраивать ваш сайт в iframe
- Mixed content — блокирует HTTP-ресурсы на SSL/TLS проверку-страницах
- Утечку данных — ограничивает домены, куда можно отправлять данные (connect-src, form-action)
Синтаксис CSP
CSP передаётся через HTTP-заголовок:
Content-Security-Policy: directive-1 value1 value2; directive-2 value3;
Каждая директива контролирует определённый тип ресурсов:
| Директива | Что контролирует | Пример |
|---|---|---|
default-src | Fallback для всех типов ресурсов | default-src 'self' |
script-src | JavaScript | script-src 'self' cdn.example.com |
style-src | CSS | style-src 'self' 'unsafe-inline' |
img-src | Изображения | img-src 'self' data: https: |
font-src | Шрифты | font-src 'self' fonts.gstatic.com |
connect-src | AJAX, WebSocket, Fetch | connect-src 'self' api.example.com |
frame-src | Iframe источники | frame-src youtube.com |
frame-ancestors | Кто может встроить вас в iframe | frame-ancestors 'none' |
form-action | Куда могут отправляться формы | form-action 'self' |
base-uri | Ограничение для тега <base> | base-uri 'self' |
object-src | Flash, Java-апплеты | object-src 'none' |
Значения источников
| Значение | Описание |
|---|---|
'self' | Только с текущего домена |
'none' | Полный запрет |
'unsafe-inline' | Разрешить inline-код (снижает защиту) |
'unsafe-eval' | Разрешить eval() (снижает защиту) |
'nonce-abc123' | Разрешить элементы с указанным nonce |
'strict-dynamic' | Доверять скриптам, загруженным доверенными скриптами |
https: | Любой HTTPS-источник |
data: | Data URI (например, data:image/png) |
*.example.com | Любой поддомен example.com |
Примеры конфигураций CSP
Базовая политика
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self'; frame-ancestors 'none'; form-action 'self'; base-uri 'self'; object-src 'none'
Сайт с Google Analytics и шрифтами
Content-Security-Policy: default-src 'self'; script-src 'self' https://www.googletagmanager.com https://www.google-analytics.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: https://www.google-analytics.com; font-src 'self' https://fonts.gstatic.com; connect-src 'self' https://www.google-analytics.com; frame-ancestors 'none'
Строгая политика с nonce
Content-Security-Policy: default-src 'self'; script-src 'nonce-rAnd0mVaLu3' 'strict-dynamic'; style-src 'self' 'nonce-rAnd0mVaLu3'; object-src 'none'; base-uri 'self'
При использовании nonce каждый тег <script> и <style> должен содержать атрибут:
<script nonce="rAnd0mVaLu3">
// Этот скрипт будет выполнен
</script>
Режим Report-Only
Перед включением CSP в боевой среде используйте режим отчётов:
Content-Security-Policy-Report-Only: default-src 'self'; report-uri /api/csp-report
В этом режиме браузер не блокирует ресурсы, а только отправляет JSON-отчёт о нарушениях. Это позволяет выявить все сторонние ресурсы, прежде чем вводить ограничения.
Пошаговое внедрение CSP
- Проверьте текущие заголовки безопасности с помощью проверки HTTP-заголовков enterno.io
- Составьте список всех сторонних ресурсов на сайте (аналитика, шрифты, CDN, виджеты)
- Создайте политику в режиме Report-Only
- Мониторьте отчёты о нарушениях 1–2 недели
- Добавьте недостающие источники в политику
- Включите CSP в принудительном режиме
- Продолжайте мониторить отчёты
Типичные ошибки
- unsafe-inline и unsafe-eval — сводят на нет защиту от XSS. По возможности используйте nonce или hash
- Слишком широкая политика —
script-src *илиdefault-src *не дают реальной защиты - Забыли про default-src — без fallback новые типы ресурсов могут загружаться откуда угодно
- Не тестировали в Report-Only — включение CSP без тестирования может сломать сайт
- Игнорирование frame-ancestors — без неё сайт остаётся уязвим к clickjacking
- Не обновляют политику — при добавлении новых интеграций CSP нужно обновлять
CSP и производительность
CSP не только повышает безопасность, но и может положительно влиять на производительность:
- Блокировка нежелательных скриптов от browser extensions
- Предотвращение загрузки вредоносных майнеров
- Ограничение количества сетевых запросов к внешним доменам
Проверка CSP
Используйте инструмент проверки HTTP-заголовков enterno.io для анализа текущей CSP-политики вашего сайта. Инструмент покажет установленный заголовок Content-Security-Policy и поможет выявить его отсутствие.
Также полезны инструменты разработчика в браузере: вкладка Console покажет все нарушения CSP с подробной информацией о заблокированных ресурсах.
Проверьте ваш сайт прямо сейчас
Проверить →