Політика безпеки вмісту
Політика безпеки вмісту – це 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. Використовуйте їх для аудиту; вони допомагають висвітлити типові помилки, але не замінюють розуміння політики.