Skip to content
Назад в блог

Content Security Policy (CSP 3): Защита приложений от XSS

3 мин. чтения
Content Security Policy (CSP 3): Защита приложений от XSS

Межсайтовый скриптинг (Cross-Site Scripting, XSS) из года в год занимает верхние строчки рейтинга OWASP Top 10. Каким бы надежным ни был бэкенд, одна пропущенная фильтрация пользовательского ввода может позволить злоумышленнику внедрить вредоносный JavaScript и украсть сессионные cookie или маркеры доступа. Основным фронтом защиты от XSS является заголовок Content Security Policy (CSP).

Рождение в Mozilla (2004–2011)

Идея о том, что страница сама объявляет свои ограничения на контент, обсуждалась ещё в 2007 году — независимо друг от друга её предлагали Gervase Markham из Mozilla и исследователь безопасности Robert «RSnake» Hansen. Brandon Sterne, тогдашний security program manager в Mozilla, вместе с инженером Sid Stamm превратил идею в рабочий код, и их черновая реализация тихо появилась в Firefox 4 в марте 2011 года под другим, ныне устаревшим заголовком: X-Content-Security-Policy. Sterne даже собрал букмарклет, который сканировал открытую страницу и предлагал стартовую политику для неё.

Через несколько месяцев Chrome выпустил свою реализацию с собственным префиксом — X-Webkit-CSP. Синтаксис у двух браузеров не совпадал, и когда в ноябре 2011 года W3C опубликовал первый черновик спецификации Content Security Policy 1.0, стандартизированная версия отличалась от того, что уже успели выпустить оба браузера — Firefox перешёл на «чистый» заголовок Content-Security-Policy и синтаксис директив CSP 1.0 только в Firefox 23, в 2013 году.

Как браузер обрабатывает Content Security Policy

Когда веб-браузер загружает HTML-страницу и видит заголовок Content-Security-Policy, он включает строгий режим белого списка (allowlist). Для каждого внешнего ресурса (картинки, скрипта, CSS-файла, WebSocket-соединения) браузер проверяет origin на соответствие объявленным правилам:

Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.jsdelivr.net; object-src 'none'; frame-ancestors 'none'; upgrade-insecure-requests;

Если скрипт пытается загрузиться с неразрешенного домена или выполниться из инлайнового <script> при запрете unsafe-inline, браузер немедленно блокирует его исполнение и генерирует ошибку в консоли:

Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self'".

Главные директивы CSP 3

  • default-src: Базовое правило по умолчанию для всех ресурсов, для которых не заданы персональные директивы.
  • script-src: Контролирует источники загрузки и выполнения JavaScript ('self', 'nonce-...', 'sha256-...').
  • style-src: Контролирует CSS-стили и таблицы.
  • img-src: Разрешённые источники изображений ('self', data:, https:).
  • connect-src: Ограничивает домены для fetch(), XMLHttpRequest, WebSocket и EventSource.
  • object-src: Управляет плагинами (Flash, Java). В современном вебе всегда рекомендуется устанавливать в 'none'.
  • frame-ancestors: Заменяет устаревший заголовок X-Frame-Options и защищает сайт от кликджекинга (Clickjacking), определяя, какие сайты могут встраивать страницу в <iframe>.
  • base-uri: Рекомендованная OWASP директива, ограничивающая, куда может указывать тег <base> — без неё легко подменить относительные ссылки на всей странице.
  • form-action: Рекомендованная OWASP директива, ограничивающая, куда могут отправляться данные форм — без неё внедрённая форма может тихо увести пароль на чужой домен.

Критические ошибки конфигурации

  1. Использование 'unsafe-inline' в script-src: полностью открывает дверь для выполнения внедрённого XSS-кода.
  2. Использование 'unsafe-eval': разрешает динамическое выполнение строк через eval(), setTimeout(string) и Function().
  3. Подстановочные знаки *: разрешение всех источников делает политику бессмысленной.

Что умеет наш CSP Header Builder

Инструмент Content Security Policy & Header Builder упрощает создание надёжных заголовков безопасности:

  • Быстрые чипы значений: переключайте 'self', 'unsafe-inline', https:, data: и 'none' в один клик без ручного набора.
  • Автоматический аудит OWASP: расчет рейтинга безопасности (A+, B, F) с детальными предупреждениями о рискованных директивах.
  • Комплексный Security Suite: опциональное добавление заголовков HSTS (Strict-Transport-Security), X-Frame-Options: DENY и X-Content-Type-Options: nosniff.
  • Многоформатный экспорт: генерация правил под Nginx (add_header), Apache (Header set), HTML <meta> и чистого HTTP-заголовка.

Быстрый старт: откройте инструмент → оставьте значения 'self' по умолчанию → чипами добавьте нужные CDN или шрифтовые источники → проверьте бейдж оценки → переключите формат экспорта под свой сервер (Nginx, Apache или <meta>-тег) → скопируйте и разверните.

Похожие инструменты

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

Что такое Content Security Policy (CSP)?

Content Security Policy — это HTTP-заголовок ответа сервера (или HTML-тег meta), который сообщает браузеру, из каких источников разрешено загружать и исполнять ресурсы (скрипты, стили, изображения, фреймы, шрифты).

Почему опасен 'unsafe-inline' в script-src?

Директива 'unsafe-inline' разрешает браузеру исполнять инлайновые теги <script> и атрибуты событий (onclick). Если на сайте есть хотя бы одна XSS-уязвимость (внедрение пользовательского HTML), 'unsafe-inline' полностью сводит защиту CSP на нет.

Чем отличаются директивы default-src и script-src?

default-src является резервной директивой (fallback) для большинства других типов ресурсов. Если конкретная директива (например, script-src или style-src) не указана явно, браузер будет использовать правила из default-src.

Можно ли задать CSP через мета-тег HTML?

Да, через <meta http-equiv="Content-Security-Policy" content="...">. Однако HTML-метатеги не поддерживают некоторые директивы, такие как frame-ancestors, report-uri и sandbox.

Автор

Fullstack Engineer

В коммерческой разработке с 2011 года — больше 15 лет. Автор двух SaaS-продуктов: TeleGo.io и LingvoHabit.com. Статьи здесь выросли из реальной клиентской и продуктовой работы.

Подробнее об автореНаписать в Telegram

Похожие статьи

GZIP VS BROTLI
GZIP VS BROTLI · '26

Как патенты на LZW привели к gzip, а веб к Brotli

История gzip, DEFLATE и Brotli, устройство двух форматов сжатия и практический выбор между размером результата, скоростью кодирования и совместимостью.

#GZip vs Brotli #история сжатия данных #Jean-loup Gailly #Brotli Google #Deflate алгоритм #LZ77 Huffman
5 мин. чтения
ФОРМАТИРОВАНИЕ RTL ТЕКСТА
ФОРМАТИРОВАНИЕ RTL ТЕКСТА · '26

Почему иврит и английский меняются местами

Как Unicode BiDi отображает иврит и арабский вместе с латиницей и кириллицей и когда использовать isolates, LRM или RLM.

#Форматирование RTL текста #Иврит и английский #Unicode BiDi controls #LRM и RLM #LRI RLI PDI #Смешанное направление текста
3 мин. чтения
СЖАТИЕ ИЗОБРАЖЕНИЙ
СЖАТИЕ ИЗОБРАЖЕНИЙ · '26

Оптимизация SVG, экспорт кода и сжатие изображений

Оптимизируйте и трансформируйте SVG, экспортируйте React, React Native, Vue, PNG или Data URI и сжимайте растровые изображения локально в браузере.

#сжатие изображений #WebP формат #оптимизация SVG #PNG vs JPEG #AVIF #SVGO
4 мин. чтения