CSPscript-src 'self''nonce-xyz'frame-ancestors'none'default-src 'self'<script>

Політика безпеки вмісту

11 хв. читанняБезпека

Політика безпеки вмісту – це HTTP-заголовок, який дозволяє веб-сторінкам декларувати, що дозволено завантажувати та виконувати. Суворий CSP перетворює XSS на набагато менший ризик: навіть якщо зловмисник впроваджує скрипт, браузер відмовляється його запускати. Компромісом є складність розгортання, тому CSP поширений не так широко, як мав би бути.

Повний текст статті подано англійською мовою нижче.

Політика безпеки вмісту (CSP) — це заголовок відповіді HTTP (та еквівалент метатегу), який повідомляє браузеру, з яких джерел дозволено завантажувати ресурси, які вбудовані сценарії можна запускати та куди слід надсилати звіти про порушення. Добре налаштований CSP значно зменшує вплив вразливостей впровадження; погано налаштований забезпечує помилкову впевненість із невеликим реальним захистом.

Що контролює CSP

Політика складається з директив, кожна з яких визначає дозволені джерела для типу ресурсу:

  • script-src — джерела JavaScript, яким дозволено завантажувати та execute
  • style-src — джерела CSS
  • img-src — джерела зображень
  • connect-src — XHR, вибірка, WebSocket targets
  • font-src — джерела шрифтів
  • media-src — джерела аудіо та відео
  • frame-src — що можна завантажити в iframes
  • frame-ancestors — що може обрамляти цю сторінку (замінює X-Frame-Options)
  • form-action — куди можна надсилати форми
  • base-uri — які URL-адреси можна встановити як base
  • upgrade-insecure-requests — автоматичне оновлення HTTP до HTTPS
  • default-src — резервний варіант для невизначених директив

A розумний початок policy

Content-Security-Policy:
  default-src 'self';
  script-src 'self' 'nonce-randomBase64Value';
  style-src 'self' 'unsafe-inline';
  img-src 'власні' дані: https:;
  connect-src 'self' https://api.example.com;
  frame-ancestors 'немає';
  base-uri 'самий';
  форма-дія 'само';
  report-uri https://example.com/csp-reports

Ця політика говорить: за замовчуванням завантажуються лише з того самого джерела, сценарії мають бути того самого походження або мати відповідний nonce, без вбудовування в iframe з інших сайтів тощо. Підхід на основі nonce запобігає більшості вбудованих сценаріїв XSS, але дозволяє законні вбудовані сценарії, які сервер видає з правильним nonce.

Nonces проти хешів проти білих списків

Три способи дозволити певні вбудовані сценарії:

  • Nonce-based. Сервер генерує свіжий випадковий nonce для кожного запиту та включає його в CSP плюс для кожного дозволеного вбудованого сценарію. Строгий і динамічний, рекомендований для нових розгортань.
  • На основі хешів. CSP визначає хеші SHA для дозволених вбудованих сценаріїв. Браузер хешує вбудовані сценарії та порівнює їх. Працює для статичних сценаріїв, вміст яких не змінюється.
  • Білий список джерел. Дозволити сценарії з певних зовнішніх доменів. Легко, але створює великі поверхні для атак — якщо будь-який домен із білого списку зламано або має відкриті перенаправлення, політика обходиться.

Ключове слово strict-dynamic (додане в CSP 3) додатково обмежує сценарії: лише недозволені сценарії можуть самі завантажувати інші сценарії, порушуючи звичайні ланцюжки XSS.

Cargo-cult anti-pattern

Багато сайтів розгортають CSP з unsafe-inline і unsafe-eval у script-src, щоб уникнути порушення існуючого коду. По суті, це взагалі не CSP — суть полягає в тому, щоб запобігти запуску вбудованих сценаріїв, а unsafe-inline усуває цей захист. Сайти з такою конфігурацією мають заголовки CSP без переваг CSP.

Шлях до фактичного значення CSP: видаліть unsafe-inline, рефакторинг коду для використання nonces або хешів і розглядайте порушення одне за одним. Боляче, але реально.

Режим лише звітів

CSP можна розгорнути в режимі лише звітів — браузер повідомляє про порушення за налаштованим URI, але не виконує їх. Корисно для перевірки нової політики на реальному трафіку без порушення роботи сайту:

Content-Security-Policy-Report-Only: ...

Стандартне розгортання: розгортання в режимі лише звітування, збирання порушень протягом кількох тижнів, виправлення законних, перехід у режим примусового виконання. Багато великих сайтів мають багатомісячне розгортання CSP через цей ітераційний цикл.

CSP і XSS

Головна перевага: навіть якщо ін’єкція XSS успішна, ін’єкційний сценарій не може запуститися, якщо він не має дійсного одноразового номера. Корисне навантаження зловмисника надходить на сторінку; браузер відмовляється його виконувати. Уразливість все ще присутня, але вплив значно зменшено.

Це не замінить виправлення XSS — це глибокий захист. Мають бути присутні обидва шари.

Підтримка браузера CSP

Усі основні браузери з 2016+. Функції CSP 3 (nonces, strict-dynamic, hashes) мають широку підтримку. Прогалини, що залишилися, пов’язані з обробкою крайніх випадків — взаємодія фрейм-предків із X-Frame-Options, різна поведінка report-uri та report-to, особливості браузера у звітах про помилки.

Операційна складність

Розгортання CSP у реальному світі складніше, ніж здається:

  • Стороннє сценарії (аналітика, реклама, моніторинг) мають бути в політиці, інакше
  • IInline обробники подій (onclick="...") порушують CSP, якщо це явно не дозволено
  • Односторінкові програми з динамічним вмістом потребують обережної одноразової обробки
  • Розширення браузера іноді можуть вводити вміст, який порушує CSP, створюючи шум
  • Різним командам можуть знадобитися різні фрагменти CSP; політика об’єднання є нетривіальною.

Багато сайтів, які повинні мати CSP, не мають, тому що експлуатаційні витрати здаються вищими, ніж уявна перевага безпеки. Вартість реальна; користь також реальна, але непомітна (ви не бачите атак, яких не було).

Часті запитання

Чи є CSP заміною санітарної обробки входу?
Ні — глибока оборона. Дезінфекція входу запобігає ін'єкції; CSP запобігає запуску ін’єкції, якщо санітарна обробка не вдається. Обидва мають бути на місці. Покладатися лише на CSP є крихким; покладатися лише на санітарну обробку протягом двох десятиліть не вдавалося.
Мені використовувати nonces чи хеші?
Nonces для динамічного вмісту (загальний випадок); хеші для фіксованих вбудованих скриптів, вміст яких ніколи не змінюється. Більшість сучасних фреймворків включають підтримку nonce. Хеші простіші концептуально, але стають тягарем обслуговування, якщо змінюється вміст сценарію.
Чому unsafe-inline все ще поширене явище?
Застарілий код, який цього вимагає (бібліотеки з вбудованими обробниками подій, старіші фреймворки). Рефакторинг займає багато часу. Чесним виправленням є рефакторинг; звичайним ярликом є ​​збереження unsafe-inline і покладатися на інші засоби захисту.
Як відстежувати порушення CSP?
Установіть звіт до або звіт-uri для кінцевої точки збирача. Багато платформ безпеки (Cloudflare, Sucuri, custom) приймають і аналізують звіти CSP. Реальний трафік створює багато шуму (розширення браузера, блокувальники реклами); Відокремлення реальних атак від шуму є частиною робочого навантаження.
Чи існують генератори найкращих практик CSP?
Такі інструменти, як Google CSP Evaluator, аналізують запропоновану політику та позначають недоліки. Обсерваторія Mozilla оцінює сторінки, включаючи якість CSP. Використовуйте їх для аудиту; вони допомагають висвітлити типові помилки, але не замінюють розуміння політики.
Пояснення політики безпеки вмісту: HTTP-заголовок, який визначає можливості вашої сторінки