CSP заголовки

Content Security Policy (CSP) — это механизм безопасности, реализованный через HTTP-заголовки, который позволяет контролировать, какие ресурсы могут загружаться и выполняться на веб-странице. CSP предотвращает ряд угроз, включая межсайтовый скриптинг (XSS) и подделку данных (data injection).


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

Каждый CSP-заголовок состоит из набора директив, задающих правила для различных типов ресурсов:

  • default-src Указывает базовый источник для всех типов контента, если другие директивы не определены. Пример:

    Content-Security-Policy: default-src 'self';
  • script-src Определяет источники для скриптов. Поддерживает ключевые слова 'self', 'unsafe-inline', 'nonce-...' и 'strict-dynamic'.

    Content-Security-Policy: script-src 'self' https://cdn.example.com 'nonce-abc123';
  • style-src Контролирует загрузку стилей. Использование 'unsafe-inline' позволяет вставлять inline CSS, однако это снижает безопасность.

    Content-Security-Policy: style-src 'self' 'unsafe-inline';
  • img-src Определяет разрешённые источники изображений.

    Content-Security-Policy: img-src 'self' https://images.example.com;
  • connect-src Контролирует доступ к сетевым ресурсам (AJAX, WebSocket, EventSource).

    Content-Security-Policy: connect-src 'self' https://api.example.com;
  • font-src Разрешает загрузку шрифтов.

    Content-Security-Policy: font-src 'self' https://fonts.gstatic.com;
  • frame-src Определяет источники для <iframe>.

    Content-Security-Policy: frame-src https://player.example.com;
  • object-src Управляет загрузкой объектов <object>, <embed> и <applet>. В современных приложениях рекомендуется ограничивать или запрещать их использование.

    Content-Security-Policy: object-src 'none';

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

Ключевые слова CSP:

  • 'self' — разрешает загрузку ресурсов с того же источника, что и страница.
  • 'none' — запрещает загрузку любых ресурсов.
  • 'unsafe-inline' — позволяет inline скрипты или стили (не рекомендуется без nonce).
  • 'unsafe-eval' — разрешает использование eval() и аналогичных функций.
  • 'strict-dynamic' — директива для скриптов, добавляющая гибкость при использовании nonce.

Nonce и hash Использование nonce или hash позволяет безопасно разрешать конкретные inline скрипты без включения 'unsafe-inline'. Пример с nonce:

<script nonce="abc123">
  console.log('Безопасный скрипт с nonce');
</script>

CSP-заголовок должен включать:

Content-Security-Policy: script-src 'nonce-abc123';

Варианты CSP-заголовков

  1. Content-Security-Policy Применяется всегда, блокируя ресурсы, нарушающие правила.

  2. Content-Security-Policy-Report-Only Заголовок используется для тестирования, не блокируя контент, а только отправляя отчёты о нарушениях на указанный URI:

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

Формат и отправка заголовков в Node.js/Express

Для установки CSP в Express используется middleware:

const express = require('express');
const helmet = require('helmet');
const app = express();

app.use(helmet.contentSecurityPolicy({
  directives: {
    defaultSrc: ["'self'"],
    scriptSrc: ["'self'", "https://cdn.example.com", "'nonce-abc123'"],
    styleSrc: ["'self'", "'unsafe-inline'"],
    imgSrc: ["'self'", "https://images.example.com"],
    connectSrc: ["'self'", "https://api.example.com"],
    fontSrc: ["'self'", "https://fonts.gstatic.com"],
    objectSrc: ["'none'"],
  }
}));

app.listen(3000);

Helmet автоматически добавляет заголовок CSP и защищает от XSS и инъекций. Важно тщательно настраивать каждую директиву, чтобы избежать блокировки легитимных ресурсов.


Отчётность и отладка CSP

  • report-uri (устаревающий) или report-to — позволяют получать уведомления о нарушениях CSP.
  • Пример:
Content-Security-Policy: default-src 'self'; report-to csp-endpoint;
  • В современных браузерах report-to используется совместно с объектом Report-To для управления отправкой JSON-отчётов о нарушениях.

Рекомендации по безопасности

  • Всегда избегать 'unsafe-inline' и 'unsafe-eval' без строгого контроля.
  • Использовать nonce для динамических inline-скриптов.
  • Разделять CSP на script-src, style-src, connect-src вместо универсального default-src.
  • Тестировать изменения через Report-Only перед внедрением.
  • Постепенно ужесточать правила CSP, чтобы не сломать функциональность сайта.

Особенности внедрения CSP для сложных приложений

Для современных приложений на React, Vue или Angular CSP требует:

  • Генерации nonce на каждый запрос.
  • Избежания inline-объявлений стилей и скриптов.
  • Использования сторонних библиотек через допустимые источники (script-src и style-src).
  • Настройки заголовков на уровне сервера и прокси, чтобы все ресурсы корректно проходили проверку CSP.

Эти практики обеспечивают надежную защиту от XSS, уменьшение риска атак через поддельные скрипты и повышают общий уровень безопасности веб-приложения.