Content Security Policy

Content Security Policy (CSP) — это механизм безопасности веб-приложений, позволяющий контролировать источники, с которых загружается контент. CSP предотвращает атаки типа Cross-Site Scripting (XSS), подмену данных и внедрение вредоносных скриптов. В Vue.js, как и в других фронтенд-фреймворках, правильная настройка CSP критически важна для защиты приложения.


Принципы работы CSP

CSP работает через заголовки HTTP (Content-Security-Policy) или мета-теги в HTML. Политика задает разрешенные источники для различных типов контента:

  • default-src — базовый источник для всех ресурсов, если не указаны более специфические директивы.
  • script-src — источники для JavaScript.
  • style-src — источники для CSS.
  • img-src — источники для изображений.
  • connect-src — источники для AJAX-запросов, WebSocket и других соединений.
  • font-src — источники для шрифтов.
  • media-src — источники для аудио и видео.
  • frame-src — источники для фреймов и iframe.

Пример базовой политики:

Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline';

Эта политика запрещает загрузку любых скриптов и стилей с внешних сайтов, кроме текущего домена, при этом разрешая встроенные стили.


CSP и Vue.js: особенности

Vue.js активно использует динамическое создание компонентов и шаблонов, что иногда вызывает конфликты с CSP:

  1. Inline-скрипты: Vue по умолчанию генерирует инлайн-скрипты при использовании шаблонов через v-on и v-html. Без 'unsafe-inline' многие из них будут блокироваться CSP.

  2. Eval и Function: Некоторые библиотеки, используемые с Vue (например, Vue Devtools), могут использовать eval или конструктор Function, что запрещено строгой CSP.

Чтобы избежать этих проблем, рекомендуется:

  • Использовать сборку Vue с runtime-only, которая не компилирует шаблоны в браузере.
  • Избегать директив v-html для вставки HTML, вместо этого использовать безопасные данные через v-text или компонентные шаблоны.
  • Использовать внешние файлы для скриптов и стилей вместо инлайна.

Настройка CSP для приложений Vue.js

Для Vue-приложений, собранных через Vue CLI или Vite, CSP можно задать несколькими способами:

1. Через серверные заголовки

Пример конфигурации Nginx:

add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' dat a:; connect-src 'self'";

Эта политика:

  • Разрешает все ресурсы только с текущего домена.
  • Позволяет использовать изображения с текущего домена и inline-данные (data:).
  • Ограничивает AJAX-запросы и WebSocket соединения текущим доменом.

2. Через мета-тег HTML

В файле index.html:

<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' dat a:;">

Метод подходит для статических сайтов и проектов без серверной настройки.


Динамическое управление CSP в Vue.js

Для SPA часто требуется разрешать динамическое подключение ресурсов (например, внешние API или CDN-шрифты). Для этого используют:

  • Nonce-токены: динамически создаются сервером для каждого запроса и добавляются к скриптам и стилям:
<script nonce="RANDOM_TOKEN">
  // код
</script>

В CSP:

script-src 'self' 'nonce-RANDOM_TOKEN';
  • Hash-токены: вычисляются хэши содержимого скриптов и указываются в CSP:
script-src 'sha256-BASE64_HASH';

Эти подходы позволяют сохранять строгую политику безопасности без отключения inline-скриптов.


Практические рекомендации для Vue-разработки

  1. Использовать runtime-only сборку Vue для минимизации инлайн-скриптов.
  2. Избегать v-html и вставки HTML из ненадежных источников.
  3. Подключать стили и скрипты через внешние файлы вместо inline.
  4. Ограничивать сторонние ресурсы через директивы script-src, style-src и connect-src.
  5. Тестировать CSP в режиме блокировки (Content-Security-Policy-Report-Only) перед полной активацией, чтобы выявить возможные конфликты.

CSP и сторонние библиотеки

Многие Vue-плагины и UI-библиотеки могут использовать динамические стили и скрипты. Чтобы обеспечить совместимость:

  • Проверять документацию на поддержку CSP.
  • Настраивать директивы style-src 'unsafe-inline' только если критично необходимо.
  • Использовать хэшированные inline-скрипты для отдельных компонентов.

Отладка CSP

Для выявления нарушений CSP:

  • Использовать консоль браузера: ошибки Refused to load указывают на заблокированные ресурсы.
  • Включать report-uri или report-to в заголовок CSP для сбора отчетов о нарушениях:
Content-Security-Policy: default-src 'self'; report-uri /csp-report-endpoint
  • Анализировать отчеты сервера, чтобы постепенно расширять политику и не допустить утечек безопасности.

CSP в Vue.js позволяет надежно защитить фронтенд, но требует внимательного подхода к динамическим скриптам и стилям. Комбинация runtime-only сборки, внешних ресурсов и хэшированных скриптов обеспечивает максимальную безопасность без снижения функциональности приложения.