Content Security Policy через meta

Content Security Policy (CSP) — это заголовок безопасности (или <meta http-equiv="Content-Security-Policy">), который ограничивает источники, откуда браузер может загружать скрипты, стили, изображения и другие ресурсы, защищая от XSS-атак.

Зачем нужно

XSS (Cross-Site Scripting) — одна из самых распространённых веб-уязвимостей: злоумышленник внедряет вредоносный скрипт, который исполняется в контексте вашей страницы. CSP ограничивает список доверенных источников для JS, CSS, шрифтов, изображений — даже если скрипт внедрён, браузер отказывается его запустить. CSP через <meta> — быстрый способ добавить базовую защиту без доступа к серверным заголовкам.

Где используется

  • Статические сайты без доступа к конфигурации сервера
  • CDN-хостинги (GitHub Pages, Netlify без custom headers)
  • HTML-страницы, встроенные в desktop-приложения
  • Прототипы и демо-страницы

Основной контент

Через HTTP-заголовок (предпочтительный способ)

Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.example.com;

Через meta-тег

<head>
  <meta http-equiv="Content-Security-Policy"
    content="default-src 'self'; script-src 'self' https://cdn.example.com">
</head>

Ограничения meta-варианта: не поддерживает директивы frame-ancestors, report-uri, sandbox.

Основные директивы

Директива Что ограничивает
default-src Источник по умолчанию для всех типов
script-src JavaScript
style-src CSS
img-src Изображения
font-src Шрифты
connect-src XHR, fetch, WebSocket
frame-src iframe
object-src <object>, <embed>

Значения источников

Значение Смысл
'self' Текущий origin
'none' Полный запрет
'unsafe-inline' Разрешить инлайн-скрипты/стили (ослабляет защиту)
'unsafe-eval' Разрешить eval
https://cdn.example.com Конкретный домен
https: Любой HTTPS
'nonce-RANDOM_VALUE' Разрешить блок с конкретным nonce

Пример реального CSP

<meta http-equiv="Content-Security-Policy"
  content="
    default-src 'self';
    script-src 'self' https://cdn.jsdelivr.net;
    style-src 'self' 'unsafe-inline' https://fonts.googleapis.com;
    font-src 'self' https://fonts.gstatic.com;
    img-src 'self' data: https://images.example.com;
    connect-src 'self' https://api.example.com;
    object-src 'none';
    base-uri 'self';
  ">

Режим только для отчётов (report-only)

Через <meta> не поддерживается — только через HTTP-заголовок:

Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-report

Полезно для тестирования политики без блокировки ресурсов.

nonce — безопасный инлайн

<!-- Сервер генерирует случайный nonce на каждый запрос -->
<meta http-equiv="Content-Security-Policy"
  content="script-src 'nonce-abc123xyz'">

<script nonce="abc123xyz">
  // Этот скрипт разрешён
  console.log('OK');
</script>

Частые ошибки

  • 'unsafe-inline' в script-src — полностью нейтрализует защиту от XSS. Используйте nonce или hash для инлайн-скриптов.
  • Блокируют собственные ресурсы — после включения CSP могут сломаться шрифты, внешние CDN, аналитика. Тестируйте в режиме report-only перед включением.
  • meta-тег после <script> в <head> — браузер применяет CSP только для ресурсов после тега. Ставьте <meta> первым в <head>.
  • Забывают data: в img-src — base64-изображения блокируются без явного data: в источниках.

Связанные темы

Ресурсы