Content Security Policy и вашият CMP: как да ги накарате да работят заедно
Два защитни слоя, които трябва да са съгласувани
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 да го изключат.