Content Security Policy і ваш CMP: як змусити CSP та згоду працювати разом
Два рівні захисту, які мають узгоджуватися
Content Security Policy (CSP) повідомляє браузеру, з яких джерел сторінці дозволено завантажувати скрипти, стилі, зображення, фрейми та мережеві запити. Платформа керування згодою виконує протилежне завдання: вона вирішує, які з цих скриптів можна запускати, виходячи з вибору користувача. Якщо налаштовувати їх окремо, вони стикаються. CMP не завантажується, бо CSP його блокує, або CSP послаблюють так сильно задля CMP і рекламних тегів, що вона вже нічого не захищає.
У цьому посібнику пояснюється, які директиви CSP зазвичай потрібні CMP, як nonce взаємодіють із впровадженням скриптів і як вносити зміни, не ламаючи банер.
Що CMP зазвичай потрібно від CSP
Точні вимоги залежать від вендора, тому завжди починайте з власної документації вашого CMP. Загалом перевірте такі директиви:
script-src— домен, з якого завантажується скрипт CMP, плюс будь-які додаткові файли скриптів, які він підвантажує.connect-src— кінцеві точки, які CMP викликає черезfetchчи XHR, наприклад для конфігурації, списку вендорів, геолокації та запису згод.style-src— домен таблиці стилів і, можливо, вбудовані стилі, якщо CMP впроваджує елемент<style>або задає атрибути style.img-src— логотипи, значки та будь-які пікселі без відстеження, які використовує CMP.font-src— якщо банер завантажує власні шрифти.frame-src— якщо CMP використовує iframe, наприклад для обміну згодою між доменами.
На сайтах із TCF пам’ятайте, що CMP також створює на сторінці фрейм-локатор з іменем __tcfapiLocator. Цей фрейм створюється без віддаленого джерела, тому запису в frame-src йому зазвичай не потрібно, але це варто підтвердити під час тестування.
Проблема вбудованої заглушки
Більшість CMP просять розмістити в head сторінки невеликий вбудований скрипт — заглушку, — щоб інші скрипти могли ставити виклики в чергу до завантаження основного CMP. Сувора CSP блокує вбудовані скрипти, якщо явно їх не дозволити. Є три варіанти:
- Nonce. Генеруйте випадкове значення для кожної відповіді, додавайте його до заголовка CSP як
'nonce-...'і до тега<script>заглушки. Це найгнучкіший варіант для динамічних сторінок. - Хеш. Додайте SHA-256-хеш точного вмісту заглушки до
script-src. Це добре працює для статичних сайтів, але будь-яка зміна заглушки, навіть пробілу, його ламає. - Розміщення заглушки у себе як зовнішнього файла на вашому домені, що покривається
'self'. Тут потрібна обережність, щоб вона й далі завантажувалася достатньо рано.
Уникайте 'unsafe-inline' як легкого шляху. Він дозволяє будь-які вбудовані скрипти, що знімає більшу частину захисту, який дає CSP.
Nonce і скрипти, що їх впроваджує CMP
CMP, який блокує скрипти до отримання згоди, часто працює так: утримує їх і впроваджує пізніше. За CSP на основі nonce ці впроваджувані скрипти теж мають бути дозволені. Є два поширені підходи:
- Передавання nonce. CMP зчитує nonce зі свого тега script і додає його до кожного скрипта, який впроваджує. Перевірте, чи підтримує це ваш CMP.
'strict-dynamic'. Це ключове слово повідомляє браузерам, що підтримують його, що скриптам, завантаженим уже довіреним скриптом, можна довіряти. Воно спрощує роботу з менеджерами тегів і CMP, що впроваджують скрипти, але означає й те, що будь-який довірений вами скрипт може завантажувати інші, тому довіряйте обережно.
Менеджери тегів порушують те саме питання. Якщо ви завантажуєте рекламні й аналітичні теги через менеджер тегів, дотримуйтеся його документації щодо nonce та переконайтеся, що CMP і менеджер тегів використовують узгоджений підхід.
Рекламні теги ускладнюють CSP
Програматик-реклама завантажує скрипти й фрейми з багатьох доменів, а список змінюється разом із партнерами з попиту. Видавці зазвичай обирають одне з двох:
- Сувора CSP на сторінках без програматик-реклами та ширша політика там, де вона показується.
- Політика, зосереджена на директивах, якими залишається посильно керувати, таких як
frame-ancestors,object-src 'none'іbase-uri, за ширших джерел скриптів.
У будь-якому разі CMP має бути в явному списку дозволених, а не покриватися лише шаблоном-підстановкою, щоб зміна CSP ніколи не вимкнула банер непомітно.
Впроваджуйте через режим Report-Only
Спершу використайте заголовок Content-Security-Policy-Report-Only. Браузер повідомляє про порушення, нічого не блокуючи, тож ви бачите, що зламала б нова політика.
- Розгорніть політику в режимі report-only із кінцевою точкою для звітів.
- Завантажуйте сторінки в чистих профілях браузера й пройдіть увесь сценарій згоди: перший візит, прийняти все, відхилити все, власний вибір, відкликання.
- Вивчіть звіти про порушення та консоль браузера на предмет заблокованих ресурсів CMP.
- Скоригуйте політику, потім перемкніться на примусове застосування.
- Залиште звіти ввімкненими й після запровадження застосування, щоб ловити регресії.
Симптоми конфлікту з CSP
- Банер не з’являється, а консоль показує порушення CSP для скрипта CMP.
- Банер з’являється, але без стилів, бо
style-srcблокує його CSS. - Вибір не зберігається, бо
connect-srcблокує виклик запису згоди. - Реклама чи аналітика не завантажуються після згоди, бо у впроваджуваних скриптів немає nonce.
__tcfapiне визначена, бо вбудовану заглушку було заблоковано.
Головні висновки
- Перевірте
script-src,connect-src,style-src,img-srcіframe-srcдля вашого CMP. - Дозволяйте вбудовану заглушку через nonce або хеш, а не через
'unsafe-inline'. - Переконайтеся, що скрипти, які впроваджуються після згоди, отримують nonce або покриваються
'strict-dynamic'. - Протестуйте кожен шлях згоди в режимі report-only до запровадження застосування.
- Тримайте CMP в явному списку дозволених, щоб зміни CSP не могли його вимкнути.