¿Qué es una Content Security Policy?
Una Content Security Policy, o CSP, es una cabecera de respuesta que indica de dónde puede cargar una página scripts, estilos, fuentes, imágenes y marcos. Todo lo que no está en la lista se bloquea.
Su tarea principal es frenar el cross-site scripting. Si un atacante logra meter un script en tu página, el navegador se niega a ejecutarlo, porque no está en la lista. Por eso una buena política convierte muchos fallos peligrosos en inofensivos.
Paso 1: empieza estricto
Empieza con la política útil más estricta. En el archivo .htaccess de Apache, añade una línea que diga que solo pueden cargarse archivos de tu propio sitio:
Header always set Content-Security-Policy "default-src 'self'" Luego recarga la página. Sigue abriendo, pero algunas partes pueden romperse. En nuestra demo, desapareció un banner de envío gratis que añadía un pequeño script en línea, y cambió la fuente del título. Es lo esperado, porque ahora la política los bloquea.
Paso 2: lee la consola
Abre las herramientas de desarrollo del navegador y mira la consola. Cada archivo bloqueado aparece ahí con la regla que lo bloqueó. En nuestra demo, la política bloqueó la hoja de estilos de Google Fonts y el script en línea.
Esta lista es tu lista de tareas. Revísala línea a línea y pregúntate en cada caso: ¿de verdad lo necesito? Si no, quítalo de la página en lugar de permitirlo.
Paso 3: permite solo lo que usas
Ahora añade excepciones exactas. Para Google Fonts, permite estilos desde fonts.googleapis.com y archivos de fuente desde fonts.gstatic.com:
Header always set Content-Security-Policy "default-src 'self'; style-src 'self' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com" Scripts en línea: usa un hash
Para un script en línea pequeño, añade su hash a script-src. El hash permite ese script exacto y nada más. Además, la consola de Chrome te muestra el hash en el mensaje de error. Cópialo en la política:
script-src 'self' 'sha256-AbC123...=' 
Si el script cambia a menudo, un nonce es más fácil: el servidor añade un valor aleatorio nuevo a la política y a cada etiqueta script en cada petición. De este modo la política sigue estricta.
Prueba antes con Report-Only
En un sitio en producción, nunca actives una política nueva sin probar. En su lugar, envíala como Content-Security-Policy-Report-Only. Así el navegador informa de cada problema en la consola pero no bloquea nada, y los visitantes nunca ven una página rota.
Header always set Content-Security-Policy-Report-Only "default-src 'self'" Recorre cada tipo de página durante unos días: inicio, artículos, pago y formularios. Cuando la consola siga limpia, cambia el nombre de la cabecera a la Content-Security-Policy real.
Ejemplos listos
Cada sitio es distinto, así que úsalos como punto de partida. Luego revísalos con la consola.
Un sitio estático sencillo
default-src 'self'; img-src 'self' data:; object-src 'none'; base-uri 'self'; frame-ancestors 'self' Un sitio con Google Analytics
default-src 'self'; script-src 'self' https://www.googletagmanager.com; connect-src 'self' https://www.google-analytics.com; img-src 'self' https://www.google-analytics.com Directivas útiles en cualquier política
object-src 'none' bloquea plugins viejos, base-uri 'self' frena un enlace base falso y frame-ancestors 'self' impide que otros sitios muestren tus páginas en un marco. Casi nunca rompen nada.
Cómo comprobar tu política
Primero, revisa tus cabeceras en vivo con nuestro HTTP Header Checker gratuito. Muestra la política exacta que reciben los visitantes y marca las partes que faltan o son débiles.
Después, abre las páginas más importantes con la consola abierta. Si no ves errores CSP en rojo, la política encaja con el sitio. Por último, revísala tras cada plugin, widget o código de seguimiento nuevo, porque cada uno puede necesitar su propia excepción.
Errores comunes
- Añadir
'unsafe-inline'para que desaparezcan los errores. También deja correr scripts inyectados, que es justo lo que la política debe frenar. - Usar un comodín como
https:en script-src, que permite scripts de cualquier sitio. - Activar una política nueva sin probarla antes en Report-Only.
- Enviar dos políticas distintas desde el servidor y un plugin; el navegador aplica las dos, así que gana la regla más estricta.
- Olvidar actualizar la política tras añadir un servicio nuevo.
En resumen: empieza estricto, lee la consola, permite hosts y hashes exactos y prueba en Report-Only. Para ver cada directiva en detalle, consulta la guía de MDN sobre CSP.
Preguntas y respuestas
¿Qué es una Content Security Policy?
Una cabecera de respuesta que dice al navegador de qué fuentes puede cargar una página scripts, estilos, fuentes y otros archivos. Todo lo demás se bloquea.
¿Por qué se rompe mi sitio al añadir una CSP?
Porque la política bloquea archivos que no están en su lista. Abre la consola, lee cada elemento bloqueado y permite solo los que de verdad necesitas.
¿Qué es Content-Security-Policy-Report-Only?
Una versión de prueba de la cabecera. El navegador informa de cada problema pero no bloquea nada, así ajustas la política sin riesgo.
¿Debo usar unsafe-inline?
No, porque permite todos los scripts en línea, también los inyectados. Usa un hash o un nonce para los pocos que necesitas.
¿Cómo permito un script en línea?
Añade su hash sha256 a script-src. Además, la consola de Chrome muestra el hash en el error, así que puedes copiarlo.
¿Qué diferencia hay entre un hash y un nonce?
Un hash coincide con un script exacto. Un nonce es un valor aleatorio que cambia en cada petición y va en la política y en la etiqueta script.
¿Cómo permito Google Fonts en una CSP?
Permite fonts.googleapis.com en style-src y fonts.gstatic.com en font-src.
¿Una CSP ayuda al SEO?
No de forma directa. Sin embargo, protege a los visitantes y a tu sitio, lo que mantiene tus páginas seguras y fiables.
¿Puedo añadir una CSP en una etiqueta meta?
Sí, con una etiqueta meta http-equiv, aunque algunas directivas, como frame-ancestors, solo funcionan en la cabecera real.
¿Cómo añado una CSP en Nginx?
Usa add_header Content-Security-Policy "..." always; en el bloque server y después recarga Nginx.
¿WordPress funciona con una CSP estricta?
A menudo sí en la parte pública, pero muchos plugins añaden scripts en línea. Por eso prueba en Report-Only y añade hashes o nonces donde haga falta.
¿Qué hace default-src?
Es la regla de reserva para cada tipo de archivo sin directiva propia, como script-src o img-src.
¿Qué es frame-ancestors?
Una directiva que dice qué sitios pueden mostrar tu página en un marco. Con 'self' impides que otros la enmarquen, lo que frena el clickjacking.
¿Puedo tener dos cabeceras CSP?
El navegador aplica las dos y un archivo debe pasar ambas. Así la página suele quedar más estricta de lo previsto, por eso deja solo una.
¿Por qué la consola muestra errores CSP de extensiones?
Porque algunas extensiones inyectan scripts y generan avisos. Prueba en una ventana privada para ver solo los errores de tu sitio.
¿Cómo permito imágenes de otro dominio?
Añade ese dominio a img-src, por ejemplo img-src 'self' https://images.example.com.
¿Qué hace object-src 'none'?
Bloquea contenido de plugins antiguos como Flash. Los sitios modernos nunca lo necesitan, así que bloquearlo es seguro.
¿Una CSP basta para frenar el XSS?
Es una capa extra fuerte, pero aun así debes escapar la salida y validar la entrada en el servidor.
¿Cómo compruebo mi CSP?
Usa nuestro HTTP Header Checker gratuito para ver la cabecera en vivo y luego recorre tus páginas principales con la consola abierta.
¿El SEO Checker revisa la CSP?
Sí. Nuestro SEO Checker muestra si se envía la cabecera y enlaza a esta guía cuando falta.