Content Security Policy y tu CMP: cómo hacer que CSP y consentimiento funcionen juntos
Dos capas de seguridad que tienen que ponerse de acuerdo
Una Content Security Policy (CSP) le dice al navegador desde qué orígenes puede una página cargar scripts, estilos, imágenes, frames y solicitudes de red. Una plataforma de gestión del consentimiento hace el trabajo contrario: decide cuáles de esos scripts pueden ejecutarse según la elección del usuario. Cuando ambas se configuran por separado, chocan. El CMP no se carga porque la CSP lo bloquea, o bien la CSP se relaja tanto para acomodar al CMP y a las etiquetas publicitarias que ya no protege nada.
Esta guía explica qué directivas de CSP suele necesitar un CMP, cómo interactúan los nonces con la inyección de scripts y cómo desplegar los cambios sin romper tu banner.
Lo que un CMP suele necesitar de la CSP
Los requisitos exactos dependen del proveedor, así que parte siempre de la documentación de tu propio CMP. En general, revisa estas directivas:
script-src— el dominio desde el que se carga el script del CMP, además de cualquier archivo de script adicional que cargue.connect-src— los endpoints a los que el CMP llama confetcho XHR, como los de configuración, lista de proveedores, geolocalización y registro del consentimiento.style-src— el dominio de las hojas de estilo y, posiblemente, estilos en línea si el CMP inyecta un elemento<style>o establece atributos de estilo.img-src— logotipos, iconos y cualquier píxel sin rastreo que use el CMP.font-src— si el banner carga sus propias fuentes.frame-src— si el CMP usa iframes, por ejemplo para compartir el consentimiento entre dominios.
En los sitios con TCF, recuerda que el CMP también crea en la página un frame localizador llamado __tcfapiLocator. Ese frame se crea sin origen remoto, por lo que normalmente no necesita una entrada en frame-src, pero conviene confirmarlo durante las pruebas.
El problema del stub en línea
La mayoría de los CMP te piden colocar un pequeño script en línea — el stub — en el head de la página, para que otros scripts puedan poner llamadas en cola antes de que se cargue el CMP principal. Una CSP estricta bloquea los scripts en línea salvo que los permitas de forma explícita. Tienes tres opciones:
- Un nonce. Genera un valor aleatorio por respuesta, añádelo a la cabecera CSP como
'nonce-...'y a la etiqueta<script>del stub. Es la opción más flexible para páginas dinámicas. - Un hash. Añade a
script-srcel hash SHA-256 del contenido exacto del stub. Funciona bien en sitios estáticos, pero cualquier cambio en el stub, incluso un espacio en blanco, lo rompe. - Alojar el stub tú mismo como un archivo externo en tu propio dominio, cubierto por
'self'. Requiere cuidado para que se cargue lo bastante pronto.
Evita 'unsafe-inline' como atajo. Permite todos los scripts en línea, lo que elimina buena parte de la protección que ofrece la CSP.
Nonces y scripts que inyecta el CMP
Un CMP que bloquea scripts hasta obtener el consentimiento suele funcionar reteniéndolos e inyectándolos más tarde. Con una CSP basada en nonces, esos scripts inyectados también deben estar permitidos. Hay dos enfoques habituales:
- Propagación del nonce. El CMP lee el nonce de su propia etiqueta de script y lo añade a cada script que inyecta. Comprueba si tu CMP lo admite.
'strict-dynamic'. Esta palabra clave indica a los navegadores compatibles que confíen en los scripts cargados por un script que ya es de confianza. Simplifica la vida con los gestores de etiquetas y los CMP que inyectan scripts, pero también significa que cualquier script en el que confíes puede cargar otros, así que confía con cuidado.
Los gestores de etiquetas plantean la misma cuestión. Si cargas etiquetas de publicidad y analítica a través de un gestor de etiquetas, sigue su documentación sobre nonces y asegúrate de que el CMP y el gestor de etiquetas usan un enfoque coherente.
Las etiquetas publicitarias complican la CSP
La publicidad programática carga scripts y frames desde muchos dominios, y la lista cambia a medida que cambian los socios de demanda. Los publishers suelen tomar una de estas dos decisiones:
- Una CSP estricta en las páginas sin publicidad programática y una política más amplia donde se muestran anuncios.
- Una política centrada en las directivas que siguen siendo manejables, como
frame-ancestors,object-src 'none'ybase-uri, mientras los orígenes de scripts siguen siendo más amplios.
En cualquier caso, el CMP debe figurar en la lista de permitidos de forma explícita, no cubierto solo por un comodín, para que un cambio de CSP nunca desactive el banner en silencio.
Despliega con el modo report-only
Usa primero la cabecera Content-Security-Policy-Report-Only. El navegador informa de las infracciones sin bloquear nada, así que puedes ver qué rompería una política nueva.
- Despliega la política en modo report-only con un endpoint de informes.
- Carga páginas en perfiles de navegador limpios y recorre el flujo de consentimiento completo: primera visita, aceptar todo, rechazar todo, elección personalizada, retirada.
- Revisa los informes de infracciones y la consola del navegador en busca de recursos del CMP bloqueados.
- Ajusta la política y luego pasa al modo de aplicación.
- Mantén los informes activados después de aplicarla para detectar regresiones.
Síntomas de un conflicto con la CSP
- El banner nunca aparece y la consola muestra una infracción de CSP para el script del CMP.
- El banner aparece pero sin estilo, porque
style-srcbloquea su CSS. - Las elecciones no se guardan, porque
connect-srcbloquea la llamada de registro del consentimiento. - Los anuncios o la analítica nunca se cargan tras el consentimiento, porque los scripts inyectados carecen de nonce.
__tcfapino está definido, porque se bloqueó el stub en línea.
Puntos clave
- Revisa
script-src,connect-src,style-src,img-srcyframe-srcpara tu CMP. - Permite el stub en línea con un nonce o un hash, no con
'unsafe-inline'. - Asegúrate de que los scripts inyectados tras el consentimiento reciban un nonce o estén cubiertos por
'strict-dynamic'. - Prueba cada ruta de consentimiento en modo report-only antes de aplicar la política.
- Mantén el CMP en la lista de permitidos de forma explícita para que los cambios de CSP no puedan desactivarlo.