CSP PARA SITIOS ESTÁTICOS
Las directivas que realmente importan para sitios estáticos en 2026, más el playbook de FAL + Supabase + Pagefind desde gautamkhorana.com.
Para qué sirve CSP
Content Security Policy es un encabezado HTTP que le dice al navegador qué orígenes pueden cargar recursos en tu página. Hecho correctamente, previene la mayoría de ataques XSS, clickjacking y cadena de suministro. Hecho incorrectamente, rompe funcionalidades silenciosamente de formas que tardan días en diagnosticar.
Los sitios estáticos tienden a subdocumentar su CSP porque el riesgo percibido es menor. La realidad es que un sitio estático con una directiva CSP faltante puede romper la reproducción de video, la carga de imágenes, la funcionalidad de búsqueda o el renderizado de fuentes, y el mensaje de la consola del navegador es la única señal que recibes.
Mapeo por tipo de recurso
La directiva que controla cada tipo de recurso:
img-src para etiquetas img. media-src para elementos video, audio, source. frame-src para iframe. connect-src para fetch y WebSocket. script-src para etiquetas script. style-src para etiquetas style y link rel=stylesheet. font-src para @font-face.
Crítico: default-src "self" NO cubre video de un host tercero. Un video de Supabase Storage fallará silenciosamente sin reproducirse si olvidas media-src; solo se verá el póster. La consola del navegador muestra la directiva que lo bloqueó; verifica eso primero cuando un video misteriosamente no se reproduce.
El incidente de mayo de 2026
En gautamkhorana.com en mayo de 2026, un MP4 de Kling alojado en Supabase Storage renderizó el HTML correctamente pero nunca se reprodujo. El póster se mostró; el video no iniciaba. Veinte minutos de depuración después, la respuesta fue que CSP no tenía directiva media-src y el navegador estaba bloqueando silenciosamente el elemento video.
La solución fue una adición de una línea a netlify.toml: media-src "self" https://*.supabase.co. El síntoma póster-pero-sin-reproducción es el patrón revelador: significa que CSP permite la imagen pero no el video.
Las librerías de búsqueda estática necesitan permisos de wasm y worker
Pagefind, Stork, Tinysearch y otras librerías de búsqueda para sitios estáticos usan WebAssembly más Web Workers. CSP debe incluir script-src "wasm-unsafe-eval" Y worker-src "self" blob: o la búsqueda se quedará colgada por siempre en "Buscando..." sin error en consola.
Segundo incidente en gautamkhorana.com en mayo de 2026: el drawer de búsqueda se quedó en "Buscando..." porque pagefind.init() falló silenciosamente cuando wasm estaba bloqueado. La solución fue agregar "wasm-unsafe-eval" a script-src y "self" blob: a worker-src.
El CSP mínimo viable para sitios con FAL + Supabase + Pagefind
Requerido:
img-src self https://*.supabase.co https://*.fal.media, para imágenes hero y activos generados por FAL. media-src self https://*.supabase.co, para video. connect-src self https://*.supabase.co, para llamadas a la API de Supabase. script-src self "wasm-unsafe-eval", para Pagefind. worker-src self blob:, para workers de Pagefind. style-src self "unsafe-inline", para estilos con scope de Astro. font-src self, para fuentes alojadas localmente.
Cada vez que añadas un nuevo host de activos (Cloudinary, Bunny, R2, cualquiera), revisa netlify.toml o vercel.json y añade el host a cada directiva que ese tipo de recurso pudiera usar. El costo de hacerlo mal es un error silencioso que aparece en producción.
Probar cambios de CSP
El modo CSP-Report-Only te permite probar cambios de política en producción sin romper nada. El navegador registra violaciones que ocurrirían en un endpoint de reporte en lugar de bloquear la solicitud. Ejecuta cualquier directiva nueva en modo report-only durante una semana, revisa las violaciones, luego promuévela a modo enforcement.
La mayoría de los fallos de CSP son silenciosos en producción. Un endpoint de reporte es la única forma de saber qué realmente rompiste. Configura uno antes de desplegar cualquier cambio de CSP no trivial.