Content Security Policy e il tuo CMP: come far funzionare insieme CSP e consenso
Due livelli di sicurezza che devono andare d’accordo
Una Content Security Policy (CSP) indica al browser da quali origini una pagina può caricare script, stili, immagini, frame e richieste di rete. Una piattaforma di gestione del consenso fa il lavoro opposto: decide quali di quegli script possono essere eseguiti in base alla scelta dell’utente. Quando le due sono configurate separatamente, si scontrano. Il CMP non si carica perché la CSP lo blocca, oppure la CSP viene allentata così tanto per accogliere il CMP e i tag pubblicitari da non proteggere più nulla.
Questa guida spiega di quali direttive CSP ha tipicamente bisogno un CMP, come i nonce interagiscono con l’iniezione di script e come rilasciare le modifiche senza rompere il banner.
Di cosa ha di solito bisogno un CMP dalla CSP
I requisiti esatti dipendono dal fornitore, quindi parti sempre dalla documentazione del tuo CMP. In generale, controlla queste direttive:
script-src— il dominio da cui si carica lo script del CMP, più gli eventuali file di script aggiuntivi che carica.connect-src— gli endpoint che il CMP chiama confetcho XHR, come quelli di configurazione, lista dei fornitori, geolocalizzazione e registrazione del consenso.style-src— il dominio dei fogli di stile ed eventualmente gli stili inline, se il CMP inietta un elemento<style>o imposta attributi di stile.img-src— loghi, icone e qualsiasi pixel senza tracciamento usato dal CMP.font-src— se il banner carica font propri.frame-src— se il CMP usa iframe, per esempio per condividere il consenso tra domini.
Sui siti con TCF, ricorda che il CMP crea nella pagina anche un frame localizzatore chiamato __tcfapiLocator. Quel frame viene creato senza sorgente remota, quindi normalmente non richiede una voce in frame-src, ma vale la pena confermarlo durante i test.
Il problema dello stub inline
La maggior parte dei CMP chiede di inserire nella head della pagina un piccolo script inline — lo stub — così che altri script possano accodare chiamate prima che il CMP principale si carichi. Una CSP rigida blocca gli script inline a meno che tu non li consenta esplicitamente. Hai tre opzioni:
- Un nonce. Genera un valore casuale per ogni risposta, aggiungilo all’intestazione CSP come
'nonce-...'e al tag<script>dello stub. È l’opzione più flessibile per le pagine dinamiche. - Un hash. Aggiungi a
script-srcl’hash SHA-256 del contenuto esatto dello stub. Funziona bene per i siti statici, ma qualsiasi modifica allo stub, anche uno spazio, lo rompe. - Ospitare lo stub in proprio come file esterno sul tuo dominio, coperto da
'self'. Richiede attenzione per garantire che si carichi abbastanza presto.
Evita 'unsafe-inline' come scorciatoia. Consente ogni script inline, eliminando gran parte della protezione che la CSP offre.
Nonce e script iniettati dal CMP
Un CMP che blocca gli script fino al consenso spesso funziona trattenendoli e iniettandoli più tardi. Con una CSP basata sui nonce, anche quegli script iniettati devono essere consentiti. Ci sono due approcci comuni:
- Propagazione del nonce. Il CMP legge il nonce dal proprio tag script e lo aggiunge a ogni script che inietta. Verifica se il tuo CMP lo supporta.
'strict-dynamic'. Questa parola chiave indica ai browser compatibili di fidarsi degli script caricati da uno script già considerato affidabile. Semplifica la vita con i tag manager e i CMP che iniettano script, ma significa anche che qualsiasi script di cui ti fidi può caricarne altri, quindi concedi fiducia con attenzione.
I tag manager pongono la stessa questione. Se carichi i tag pubblicitari e di analytics tramite un tag manager, segui la sua documentazione sui nonce e assicurati che CMP e tag manager adottino un approccio coerente.
I tag pubblicitari rendono la CSP più difficile
La pubblicità programmatica carica script e frame da molti domini, e l’elenco cambia al cambiare dei partner di domanda. I publisher fanno di solito una di queste due scelte:
- Una CSP rigida sulle pagine senza pubblicità programmatica e una policy più ampia dove girano gli annunci.
- Una policy concentrata sulle direttive che restano gestibili, come
frame-ancestors,object-src 'none'ebase-uri, mentre le origini degli script restano più ampie.
In entrambi i casi, il CMP dovrebbe essere nella lista di autorizzazione in modo esplicito, non coperto solo da un carattere jolly, così che una modifica alla CSP non disattivi mai il banner in silenzio.
Rilascia con la modalità report-only
Usa prima l’intestazione Content-Security-Policy-Report-Only. Il browser segnala le violazioni senza bloccare nulla, così puoi vedere cosa romperebbe una nuova policy.
- Distribuisci la policy in modalità report-only con un endpoint di segnalazione.
- Carica le pagine in profili del browser puliti e percorri l’intero flusso di consenso: prima visita, accetta tutto, rifiuta tutto, scelta personalizzata, revoca.
- Esamina i report delle violazioni e la console del browser alla ricerca di risorse del CMP bloccate.
- Regola la policy, poi passa all’applicazione effettiva.
- Mantieni attive le segnalazioni dopo l’applicazione per individuare le regressioni.
Sintomi di un conflitto con la CSP
- Il banner non compare mai e la console mostra una violazione CSP per lo script del CMP.
- Il banner compare ma senza stile, perché
style-srcblocca il suo CSS. - Le scelte non vengono salvate, perché
connect-srcblocca la chiamata di registrazione del consenso. - Gli annunci o l’analytics non si caricano mai dopo il consenso, perché gli script iniettati non hanno un nonce.
__tcfapinon è definito, perché lo stub inline è stato bloccato.
Punti chiave
- Controlla
script-src,connect-src,style-src,img-srceframe-srcper il tuo CMP. - Consenti lo stub inline con un nonce o un hash, non con
'unsafe-inline'. - Assicurati che gli script iniettati dopo il consenso ricevano un nonce o siano coperti da
'strict-dynamic'. - Testa ogni percorso di consenso in modalità report-only prima di applicare la policy.
- Mantieni il CMP esplicitamente nella lista di autorizzazione così che le modifiche alla CSP non possano disattivarlo.