Content Security Policy (CSP) sin romper tu sitio

Security2026-09-18TryQuickToolBox

Has oído que Content Security Policy (CSP) es esencial para proteger tu sitio de ataques de cross-site scripting (XSS) e inyección de datos. Pero cuando intentas añadirlo, tu sitio se rompe: las imágenes desaparecen, los scripts dejan de ejecutarse, los estilos se pierden. Parece un intercambio entre seguridad y funcionalidad. No tiene por qué serlo.

En esta guía, aprenderás un enfoque práctico paso a paso para implementar CSP sin romper tu sitio. Cubriremos las directivas principales, cómo usar nonces y hashes, y cómo probar de forma segura. Al final, tendrás un CSP funcional que mejora la seguridad sin sacrificar la experiencia del usuario.

¿Qué es CSP y por qué rompe los sitios?

Content Security Policy es un estándar de seguridad del navegador que te permite restringir qué recursos (scripts, estilos, imágenes, fuentes, etc.) se pueden cargar en tu página. Se entrega mediante una cabecera HTTP como Content-Security-Policy: default-src 'self'.

CSP rompe los sitios porque bloquea cualquier recurso que no coincida con tu política. Si tienes scripts inline, scripts externos de CDNs o estilos inline, se bloquearán a menos que los permitas explícitamente. El comportamiento predeterminado es bloquear todo lo no permitido, por lo que una política estricta puede romper un sitio rápidamente.

La clave es comenzar con una política permisiva y endurecerla gradualmente mientras monitoreas las violaciones.

Directivas CSP principales que debes conocer

CSP utiliza directivas para controlar diferentes tipos de recursos. Estas son las más comunes:

Puedes establecer múltiples directivas en una cabecera, separadas por punto y coma. Por ejemplo:

Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.cdn.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https://images.example.com

Cada directiva acepta una lista de fuentes separadas por espacios. Las fuentes pueden ser palabras clave como 'self', 'unsafe-inline', 'unsafe-eval', o URLs, o nonces/hashes.

Paso a paso: Implementa CSP sin romper tu sitio

Sigue estos pasos para implementar CSP de forma segura.

  1. Comienza con una política de solo informe. Usa la cabecera Content-Security-Policy-Report-Only en lugar de la de aplicación. Esto te permite ver qué se bloquearía sin bloquearlo realmente.
  2. Establece una política permisiva. Comienza con algo como default-src 'self' 'unsafe-inline' 'unsafe-eval' https: para permitir la mayoría de las cosas. Esto minimiza las roturas.
  3. Recopila informes de violaciones. Configura report-uri a un endpoint que registre las violaciones. Revisa estos informes para identificar los recursos bloqueados.
  4. Corrige las violaciones. Actualiza tu código para evitar scripts/estilos inline, o añade nonces/hashes. Mueve los recursos externos a dominios permitidos.
  5. Endurece la política gradualmente. Elimina 'unsafe-inline' y 'unsafe-eval' una vez que hayas refactorizado. Reduce los dominios permitidos.
  6. Cambia al modo de aplicación. Una vez que los informes no muestren bloqueos inesperados, cambia la cabecera a Content-Security-Policy (sin -Report-Only).
  7. Monitorea continuamente. Mantén el endpoint de informes activo para detectar nuevos problemas.

Este enfoque incremental asegura que no rompas tu sitio mientras mejoras la seguridad.

Uso de nonces y hashes para scripts inline

Los scripts inline son una causa común de rotura de CSP. En lugar de permitir 'unsafe-inline', usa un nonce (número usado una vez) o un hash.

Enfoque de nonce: Genera un nonce aleatorio por solicitud, añádelo a tu cabecera CSP e inclúyelo en tus etiquetas script.

Content-Security-Policy: script-src 'nonce-abc123'
<script nonce="abc123">...</script>

Enfoque de hash: Calcula el hash SHA de tu script inline y añádelo a la política.

Content-Security-Policy: script-src 'sha256-xyz...'

Los hashes son mejores para scripts inline estáticos que no cambian con frecuencia. Los nonces son mejores para contenido dinámico.

Para los estilos, también puedes usar nonces o hashes, pero ten en cuenta que style-src con nonces no cubre los atributos de estilo inline (por ejemplo, style="..."). Para esos, necesitas 'unsafe-inline' o refactorizar a clases.

Directivas CSP comunes y su impacto

Directiva Qué controla Fuentes comunes
default-src Respaldo para todos los tipos de recursos 'self', https:
script-src Fuentes de JavaScript 'self', 'nonce-...', 'sha256-...', https://cdn.com
style-src Fuentes de CSS 'self', 'unsafe-inline', 'nonce-...'
img-src Fuentes de imágenes 'self', data:, https://images.com
connect-src AJAX, WebSocket, fetch 'self', https://api.com
font-src Fuentes web 'self', https://fonts.gstatic.com
frame-src Iframes 'self', https://youtube.com

Usa esta tabla como referencia rápida al construir tu política.

Pruebas y monitoreo de tu CSP

Antes de aplicar, prueba a fondo. Usa las herramientas de desarrollador del navegador: la pestaña Console muestra las violaciones de CSP como errores. La pestaña Network muestra la cabecera CSP.

Para pruebas automatizadas, considera herramientas como CSP Evaluator de Google (en línea) o el paquete npm csp_evaluator. Estos ayudan a identificar políticas débiles.

Configura un endpoint de informes para recopilar violaciones en producción. Puedes usar un servicio como Report URI o construir tu propio endpoint que registre en un archivo o base de datos. Analiza los informes regularmente para detectar nuevos problemas.

Recuerda: CSP no es una bala de plata. Es una capa de defensa. Combínalo con validación de entrada, codificación de salida y otras mejores prácticas de seguridad.

Preguntas frecuentes

¿Cuál es la diferencia entre Content-Security-Policy y Content-Security-Policy-Report-Only?

La cabecera de aplicación (Content-Security-Policy) bloquea las violaciones. La cabecera de solo informe (Content-Security-Policy-Report-Only) solo informa de las violaciones sin bloquear, lo que te permite probar una política de forma segura.

¿Puedo usar CSP con manejadores de eventos inline como onclick?

No, los manejadores de eventos inline son bloqueados por CSP a menos que uses 'unsafe-inline' (lo cual no se recomienda) o refactorices para usar addEventListener. Para una mejor seguridad, evita los manejadores de eventos inline.

¿Cómo permito Google Analytics con CSP?

Añade los dominios de Google Analytics a tus directivas script-src y connect-src. Por ejemplo: script-src 'self' https://www.googletagmanager.com; connect-src 'self' https://www.google-analytics.com. Consulta la documentación de Google para los requisitos más recientes.

Implementar CSP no tiene que ser un proceso doloroso. Con un enfoque gradual, puedes proteger a tus usuarios de XSS y otros ataques sin interrumpir tu sitio. Comienza con el modo de solo informe, corrige las violaciones y endurece tu política con el tiempo.

Si necesitas formatear o validar rápidamente archivos de configuración JSON para tus informes CSP, prueba nuestro JSON Formatter para embellecer y depurar tus datos JSON.