Content-Security-Policy (CSP) es una de las cabeceras de seguridad mas potentes disponibles, pero tambien una de las mas complicadas de aplicar correctamente en WordPress. La razon es sencilla: el nucleo de WordPress, los temas y los plugins adoran usar scripts y estilos en linea. Una CSP estricta los bloquea por defecto, lo que significa que tu sitio puede romperse de formas inesperadas si no planificas con cuidado. Esta guia te lleva por todo el proceso, desde entender que hace CSP hasta desplegar una politica lista para produccion.
Por que la CSP es especialmente complicada en WordPress
La mayoria de sitios WordPress dependen mucho de patrones que CSP esta disenada para restringir. Estos son los problemas mas comunes con los que te encontraras:
- Scripts en linea: muchos plugins inyectan JavaScript directamente en el HTML mediante etiquetas
<script>sin atributosrc. Constructores de paginas como Elementor, WPBakery y Divi lo hacen en gran medida. - Estilos en linea: el Personalizador de WordPress, los bloques de Gutenberg y la mayoria de los temas anaden atributos
styleo bloques<style>a la pagina. Una CSP estricta sin'unsafe-inline'para estilos romperia el aspecto visual de tu sitio. - Uso de eval(): algunos plugins usan la funcion
eval()de JavaScript o construcciones similares, lo que requiere la directiva'unsafe-eval'. - Recursos de terceros: Google Analytics, Google Fonts, reCAPTCHA, videos de YouTube embebidos, widgets de redes sociales. Cada uno necesita su propia entrada en CSP.
Por todo esto, nunca debes copiar una CSP de otra web y pegarla en tu configuracion de WordPress. Cada sitio WordPress tiene una combinacion unica de plugins y temas, asi que cada CSP debe adaptarse de forma individual.
Empieza con el modo report-only para descubrir que se rompe
La forma mas segura de empezar es con la cabecera Content-Security-Policy-Report-Only. Esta cabecera se comporta exactamente como CSP, salvo que en realidad no bloquea nada. En su lugar, registra las violaciones en la consola del navegador para que veas que evitaria tu politica. Nada en tu sitio se rompe, pero obtienes visibilidad total.
Anade esto a tu archivo .htaccess (Apache):
<IfModule mod_headers.c>
Header set Content-Security-Policy-Report-Only "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data: https://fonts.gstatic.com; connect-src 'self';"
</IfModule>O para Nginx:
add_header Content-Security-Policy-Report-Only "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data: https://fonts.gstatic.com; connect-src 'self';" always;Dejalo activo al menos unos dias y navega por todas las paginas importantes de tu sitio (inicio, entradas del blog, formulario de contacto, checkout de WooCommerce si procede). Cada pagina puede cargar plugins y recursos diferentes.
Como encontrar violaciones de CSP en la consola del navegador
Tras activar el modo Report-Only, abre tu sitio en Chrome o Firefox y pulsa F12 para abrir las DevTools. Ve a la pestana Consola. Las violaciones de CSP aparecen como mensajes de advertencia con esta forma:
[Report Only] Refused to load the script 'https://www.googletagmanager.com/gtag/js' because it violates the following Content Security Policy directive: "script-src 'self' 'unsafe-inline'".
Cada mensaje de violacion te dice exactamente que se ha bloqueado y que directiva lo causo. Recopila todos esos mensajes y usalos para construir tu lista de permitidos. Visita cada pagina importante de tu sitio, incluidas las paginas con formularios, sliders, mapas y cualquier pagina que cargue plugins unicos.
Las directivas CSP clave para WordPress
Estas son las directivas que probablemente tendras que configurar:
- default-src: el valor por defecto para todos los tipos de recursos no listados explicitamente. Establecelo a
'self'como linea base. - script-src: controla desde donde se puede cargar JavaScript. Casi seguro necesitaras
'unsafe-inline'en WordPress. Si algun plugin usaeval(), tambien necesitaras'unsafe-eval'. - style-src: controla desde donde se puede cargar CSS. WordPress casi siempre necesita
'unsafe-inline'aqui. - img-src: controla las fuentes de imagenes. Usa
'self' data: https:para permitir tus propias imagenes, URIs data (que muchos plugins utilizan) y cualquier imagen por HTTPS. - font-src: controla la carga de fuentes. Si usas Google Fonts, anade
https://fonts.gstatic.com. - connect-src: controla desde donde JavaScript puede hacer peticiones de red (AJAX, fetch, WebSocket). El admin de WordPress lo usa mucho para la REST API y la API Heartbeat.
- frame-src: controla que dominios pueden cargarse en iframes. Necesario para incrustaciones de YouTube (
https://www.youtube.com), Google Maps (https://www.google.com) y reCAPTCHA (https://www.google.com). - media-src: controla las fuentes de audio y video. Normalmente
'self'es suficiente, salvo que incrustes medios externos. - object-src: controla plugins como Flash. Establecelo a
'none', ya que Flash esta muerto y esta directiva previene en su mayoria vectores de ataque heredados.
Construye tu politica paso a paso
Empieza con una linea base restrictiva y anade excepciones a medida que descubras violaciones:
- Empieza con una politica minima:
default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self'; - Anade unsafe-inline para scripts y estilos: casi siempre es necesario en WordPress.
script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; - Anade URIs data para imagenes y fuentes: muchos plugins usan imagenes en base64.
img-src 'self' data: https:; font-src 'self' data:; - Permite tu CDN: si usas un CDN como Cloudflare o BunnyCDN, anade su dominio a
script-src,style-src,img-srcyfont-src. - Anade los servicios de terceros uno a uno: por cada violacion CSP en la consola, anade el dominio especifico a la directiva correspondiente.
Entradas comunes de la lista de permitidos para sitios WordPress
Aqui tienes una referencia de dominios que podrias necesitar para integraciones populares de WordPress:
- Google Fonts:
style-src https://fonts.googleapis.comyfont-src https://fonts.gstatic.com - Google Analytics / GA4:
script-src https://www.googletagmanager.com https://www.google-analytics.comyconnect-src https://www.google-analytics.com https://analytics.google.com - Google Maps:
script-src https://maps.googleapis.comyframe-src https://www.google.com - Incrustaciones de YouTube:
frame-src https://www.youtube.com https://www.youtube-nocookie.com - reCAPTCHA:
script-src https://www.google.com https://www.gstatic.comyframe-src https://www.google.com - Gravatar:
img-src https://secure.gravatar.com https://www.gravatar.com - WordPress.org:
img-src https://s.w.org https://ps.w.org(para iconos de plugins/temas en el admin)
Un ejemplo completo de CSP para WordPress
Aqui tienes una CSP realista para un sitio WordPress que usa Google Analytics, Google Fonts, incrustaciones de YouTube y Gravatar. Adaptala a tus necesidades especificas:
<IfModule mod_headers.c>
Header set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://www.googletagmanager.com https://www.google-analytics.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: https: https://secure.gravatar.com; font-src 'self' data: https://fonts.gstatic.com; connect-src 'self' https://www.google-analytics.com https://analytics.google.com; frame-src https://www.youtube.com https://www.youtube-nocookie.com; object-src 'none'; base-uri 'self'; form-action 'self';"
</IfModule>Plugins de WordPress para gestionar CSP
Si te resulta intimidante editar archivos de configuracion del servidor, estos plugins pueden ayudarte:
- HTTP Headers: un plugin gratuito que te permite definir todas las cabeceras de seguridad desde el admin de WordPress. Soporta CSP con una interfaz amigable donde puedes anadir fuentes por directiva.
- Really Simple SSL Pro: incluye un modulo de Content Security Policy con registro de violaciones y soluciones en un clic para problemas habituales.
- Plugin de CSP de Jeremykendall: una opcion ligera centrada unicamente en la gestion de CSP.
Ten en cuenta que las cabeceras CSP basadas en plugins solo se envian para paginas procesadas por WordPress. Los recursos estaticos servidos directamente por tu servidor web no llevaran la cabecera. Para una proteccion completa, se prefiere la configuracion a nivel de servidor.
Pasar de Report-Only al modo de aplicacion
Una vez que has corrido en modo Report-Only durante al menos una semana y has resuelto todas las violaciones, estas listo para hacer el cambio. Simplemente cambia el nombre de la cabecera de Content-Security-Policy-Report-Only a Content-Security-Policy. Manten abierta la consola del navegador durante las primeras horas y vigila cualquier violacion que pudieras haber pasado por alto. Si algo se rompe, siempre puedes volver a Report-Only mientras lo arreglas.
Verifica tu CSP con InspectWP
Tras implementar tu Content-Security-Policy, ejecuta un nuevo escaneo de InspectWP. La seccion de cabeceras de seguridad de tu informe mostrara si la cabecera CSP esta presente y si esta en modo Report-Only o de aplicacion. Usalo como una comprobacion rapida tras cualquier cambio para confirmar que tu politica se sigue enviando correctamente.