Si has escaneado tu sitio web con herramientas de seguridad como Wapiti, Acunetix o OWASP ZAP, es probable que hayas encontrado esta advertencia:
WARNING: CSP is not set for URL: https://tu-sitio.com/
En este artículo explicaremos qué es el Content Security Policy, por qué es importante implementarlo y cómo configurarlo correctamente en WordPress mediante el archivo .htaccess.
#Qué es el Content Security Policy (CSP)
El Content Security Policy es una capa de seguridad adicional implementada mediante cabeceras HTTP que ayuda a proteger aplicaciones web contra varios tipos de ataques:
- Cross-Site Scripting (XSS): Previene la inyección y ejecución de scripts maliciosos
- Clickjacking: Evita que la página sea cargada en iframes no autorizados
- Inyección de código: Bloquea la ejecución de código no autorizado
- Carga de recursos maliciosos: Controla qué scripts, estilos e imágenes pueden cargarse
El CSP funciona como una política de lista blanca que especifica exactamente qué fuentes de contenido son legítimas, bloqueando automáticamente cualquier recurso que no cumpla con las reglas establecidas.
#Importancia de Implementar CSP
La ausencia de una política CSP expone tu sitio web a múltiples vectores de ataque:
#Vulnerabilidades de Seguridad
- Ataques XSS: Permite la inyección de JavaScript malicioso que puede robar credenciales, cookies de sesión o datos sensibles
- Secuestro de sesiones: Scripts no autorizados pueden acceder a las cookies de autenticación de los usuarios
- Defacement: Modificación no autorizada del contenido visible del sitio
- Phishing: Inyección de formularios falsos para recolección fraudulenta de datos
#Impacto en Auditorías de Seguridad
Las herramientas de auditoría de seguridad modernas penalizan significativamente los sitios sin CSP configurado. Esto afecta:
- Puntuaciones de seguridad en plataformas como SecurityHeaders.com y Mozilla Observatory
- Cumplimiento de estándares de seguridad (PCI DSS, OWASP Top 10)
- Confianza de navegadores modernos que priorizan sitios con políticas de seguridad robustas
#Verificación de CSP Actual
Antes de implementar cambios, es importante verificar el estado actual de las cabeceras de seguridad de tu sitio.
#Método 1: Herramientas en Línea
- SecurityHeaders.com – Análisis completo de cabeceras de seguridad
- Mozilla Observatory – Evaluación de seguridad integral
#Método 2: Verificación mediante PowerShell (Windows)
Invoke-WebRequest -Uri "https://tu-sitio.com/" -Method Head | Select-Object -ExpandProperty Headers#Método 3: Verificación mediante Terminal (Linux/macOS)
curl -I https://tu-sitio.com/ | grep -i "content-security"Si la cabecera Content-Security-Policy no aparece en los resultados, el CSP no está configurado.
#
#Implementación de CSP mediante .htaccess
#Ventajas de usar .htaccess sobre functions.php
La configuración de CSP mediante .htaccess ofrece múltiples ventajas sobre la implementación en functions.php:
- Rendimiento superior: Las directivas se ejecutan a nivel de servidor Apache, antes de la inicialización de PHP
- Mayor seguridad: No depende de que WordPress esté completamente cargado
- Independencia de tema: Permanece activo incluso al cambiar de tema o durante actualizaciones
- Mantenimiento simplificado: Centraliza todas las configuraciones de servidor en un único archivo
- Compatibilidad: Funciona incluso si hay errores fatales de PHP en WordPress
#Procedimiento de Implementación
Paso 1: Realizar copia de seguridad
Antes de realizar cualquier modificación en el archivo .htaccess, es imperativo crear una copia de seguridad completa. Este archivo controla aspectos críticos del servidor y errores de sintaxis pueden resultar en errores 500.
Paso 2: Acceder al archivo .htaccess
El archivo .htaccess se encuentra en el directorio raíz de la instalación de WordPress. Puedes acceder a él mediante:
- Cliente FTP (FileZilla, WinSCP, Cyberduck)
- Panel de control del hosting (cPanel, Plesk, DirectAdmin)
- Administrador de archivos integrado del hosting
- SSH (para usuarios avanzados)
Paso 3: Localizar la sección de cabeceras mod_headers
Busca el bloque <IfModule mod_headers.c> en tu archivo. Si ya tienes configuradas cabeceras de seguridad como Strict-Transport-Security, X-Frame-Options o X-Content-Type-Options, este es el lugar correcto.
Si no existe esta sección, créala antes del bloque # BEGIN WordPress.
Paso 4: Agregar la directiva CSP
Dentro del bloque <IfModule mod_headers.c>, agrega la siguiente línea:
<IfModule mod_headers.c>
# Content Security Policy - Protección contra XSS e inyección de código
# Configuración optimizada para WordPress con compatibilidad de plugins y temas
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://www.google.com https://www.gstatic.com https://*.googleapis.com https://www.google-analytics.com https://www.googletagmanager.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' data: https://fonts.gstatic.com; img-src 'self' data: https: http:; connect-src 'self' https://www.google-analytics.com; frame-src 'self' https://www.google.com https://www.youtube.com; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'self';"
</IfModule>Paso 5: Guardar y verificar
Guarda los cambios y verifica que el sitio funciona correctamente. Si encuentras un error 500, restaura inmediatamente la copia de seguridad.
#Análisis de la Política CSP Implementada
A continuación se explica cada directiva de la política de seguridad configurada:
| Directiva | Función |
|---|---|
default-src 'self' |
Establece que por defecto solo se permiten recursos del mismo origen (mismo dominio) |
script-src 'self' 'unsafe-inline' 'unsafe-eval' |
Permite scripts del mismo dominio, scripts inline y evaluación dinámica (requerido por WordPress y muchos plugins) |
style-src 'self' 'unsafe-inline' |
Permite hojas de estilo del mismo dominio, estilos inline y Google Fonts |
img-src 'self' data: https: |
Permite imágenes del mismo dominio, data URIs y cualquier URL HTTPS externa |
font-src 'self' data: |
Permite fuentes del mismo dominio, data URIs y Google Fonts |
connect-src 'self' |
Controla las conexiones AJAX, WebSocket y EventSource |
frame-src 'self' |
Controla qué URLs pueden cargarse en iframes (incluye YouTube y Google) |
object-src 'none' |
Bloquea completamente plugins como Flash, Java applets y ActiveX |
base-uri 'self' |
Previene modificaciones maliciosas del elemento <base> |
form-action 'self' |
Restringe los destinos de envío de formularios al mismo dominio |
frame-ancestors 'self' |
Controla qué sitios pueden incluir esta página en iframes (protección contra clickjacking) |
#Verificación Post-Implementación
Después de implementar los cambios, es fundamental verificar que la política CSP está activa y funcionando correctamente.
#Verificación mediante SecurityHeaders.com
- Accede a https://securityheaders.com
- Introduce la URL de tu sitio web
- Analiza el resultado y verifica que aparece la cabecera Content-Security-Policy
- Revisa la calificación de seguridad, que debería mejorar significativamente
#Verificación mediante Herramientas de Desarrollo del Navegador
- Abre tu sitio web en Chrome, Firefox o Edge
- Presiona
F12para abrir las herramientas de desarrollo - Navega a la pestaña Network (Red)
- Recarga la página con
Ctrl+F5oCmd+Shift+R - Selecciona el primer recurso (documento HTML principal)
- En la sección Headers (Cabeceras), busca Response Headers
- Verifica la presencia de
content-security-policy
#Verificación mediante Wapiti
Ejecuta nuevamente el escaneo de seguridad:
wapiti -u https://tu-sitio.com/ --scope pageLa advertencia «CSP is not set» debe haber desaparecido del reporte de vulnerabilidades.
#Configuración Avanzada y Personalización
#Adaptación para Servicios de Terceros
Dependiendo de los servicios externos que utilices, puede ser necesario ajustar la política CSP:
- Facebook Pixel: Agrega
https://connect.facebook.netyhttps://www.facebook.comascript-src - Cloudflare Analytics: Agrega
https://static.cloudflareinsights.comascript-src - CDN externos: Incluye el dominio del CDN en las directivas correspondientes (
script-src,style-src,img-src) - Stripe/PayPal: Agrega sus respectivos dominios a
script-srcyframe-src - Vimeo: Agrega
https://player.vimeo.comaframe-src
#Modo Report-Only para Pruebas
Si deseas probar una política CSP sin bloquear recursos, utiliza el modo de solo reporte:
Header always set Content-Security-Policy-Report-Only "default-src 'self'; script-src 'self';"En este modo, el navegador reportará violaciones en la consola de desarrollo sin bloquear los recursos. Esto permite identificar qué ajustes son necesarios antes de implementar la política en modo de aplicación.
#Configuración de Reportes de Violación
Para monitorear violaciones de CSP en producción, puedes configurar un endpoint de reportes:
Header always set Content-Security-Policy "default-src 'self'; ... report-uri /csp-violation-report-endpoint/"Esto requiere implementar un script en el servidor que reciba y registre los reportes de violación.
#Solución de Problemas Comunes
#Error 500 Internal Server Error
Causa: El módulo mod_headers no está habilitado en Apache.
Solución: Restaura inmediatamente la copia de seguridad del .htaccess. Contacta con tu proveedor de hosting para habilitar mod_headers o solicita que implementen la política CSP a nivel de servidor.
#Recursos CSS o JavaScript Bloqueados
Causa: La política CSP está bloqueando recursos legítimos.
Solución:
- Abre la consola del navegador (F12)
- Identifica qué recursos están siendo bloqueados
- Agrega los dominios necesarios a las directivas correspondientes
- Limpia la caché del navegador y del servidor
#Google Fonts no se Cargan
Causa: Faltan permisos para los dominios de Google Fonts.
Solución: Verifica que tu política incluye:
https://fonts.googleapis.comenstyle-srchttps://fonts.gstatic.comenfont-src
#Videos Embebidos no se Reproducen
Causa: El dominio del servicio de video no está autorizado en frame-src.
Solución: Agrega el dominio correspondiente:
- YouTube:
https://www.youtube.com - Vimeo:
https://player.vimeo.com - Dailymotion:
https://www.dailymotion.com
#Mejores Prácticas de Seguridad
La implementación de CSP debe formar parte de una estrategia de seguridad integral:
#Políticas de Seguridad Complementarias
- Strict-Transport-Security (HSTS): Fuerza el uso de HTTPS
- X-Frame-Options: Protección adicional contra clickjacking
- X-Content-Type-Options: Previene MIME type sniffing
- Referrer-Policy: Controla la información enviada en el header Referer
- Permissions-Policy: Controla el acceso a APIs del navegador
#Mantenimiento Continuo
- Mantén WordPress, temas y plugins actualizados
- Realiza auditorías de seguridad periódicas con herramientas como Wapiti, Acunetix o Qualys
- Implementa autenticación de dos factores (2FA) para usuarios administradores
- Configura copias de seguridad automáticas diarias
- Monitorea logs del servidor en busca de actividad sospechosa
- Utiliza contraseñas robustas y únicas para cada servicio
#
#Referencias Técnicas
- MDN Web Docs: Content Security Policy
- Google CSP Evaluator
- CSP Quick Reference Guide
- Mozilla Observatory
- W3C Content Security Policy Level 3
- OWASP CSP Cheat Sheet
La implementación de Content Security Policy mediante el archivo .htaccess representa una mejora significativa en la postura de seguridad de cualquier sitio WordPress. Esta configuración proporciona:
- Protección efectiva contra ataques de Cross-Site Scripting (XSS)
- Control granular sobre los recursos que pueden cargarse en el sitio
- Reducción de la superficie de ataque disponible para atacantes
- Cumplimiento de estándares modernos de seguridad web
- Mejora en las calificaciones de auditorías de seguridad
La seguridad web es un proceso continuo que requiere atención constante. El CSP debe considerarse como una capa más dentro de una estrategia de defensa en profundidad que incluya actualizaciones regulares, monitoreo activo y aplicación de mejores prácticas de desarrollo seguro.
