WordPress impulsa más del 40% de la web, convirtiéndolo en el CMS más atacado por bots automatizados, script kiddies y atacantes sofisticados por igual. Cada sitio WordPress sin protección enfrenta miles de solicitudes maliciosas diariamente — intentos de inicio de sesión por fuerza bruta, ataques de amplificación XML-RPC, sondeos de inyección SQL y escaneos de recorrido de directorios. El Web Application Firewall (WAF) de Cloudflare proporciona una potente capa de defensa gratuita que detiene estos ataques en el borde, antes de que lleguen a tu servidor. En esta guía, configurarás reglas WAF personalizadas que bloquean los vectores de ataque más comunes de WordPress.
Requisitos Previos
- Una cuenta de Cloudflare (el plan gratuito permite hasta 5 reglas personalizadas)
- El DNS de tu dominio administrado por Cloudflare (proxy con nube naranja activa)
- Una instalación de WordPress en funcionamiento
- Acceso de administrador al panel de Cloudflare
- Tu dirección IP pública actual (para incluir en la lista blanca del acceso admin)
Por Qué WordPress Necesita Protección WAF
Los sitios WordPress enfrentan un bombardeo incesante de ataques automatizados. Según datos de Wordfence, un sitio WordPress típico recibe más de 90,000 intentos de inicio de sesión maliciosos por mes. Los endpoints más explotados son:
- xmlrpc.php — utilizado para amplificación de fuerza bruta (una sola solicitud puede probar cientos de contraseñas), abuso de pingback para DDoS y ataques SSRF
- wp-login.php — objetivo de bots de credential stuffing que ejecutan listas de contraseñas filtradas
- wp-admin/ — sondeado en busca de acceso no autenticado a funciones de administración
- wp-json/wp/v2/ — la enumeración de la REST API expone nombres de usuario y estructura de contenido
- Query strings — intentos de inyección SQL vía
?id=1 UNION SELECT, recorrido de directorios vía../../etc/passwd
Un firewall a nivel de servidor como iptables solo ve direcciones IP. El WAF de Cloudflare inspecciona las solicitudes HTTP en la capa 7 — puede analizar rutas URI, query strings, encabezados, métodos de solicitud y user agents. Esto te permite escribir reglas precisas que bloquean ataques sin afectar a los visitantes legítimos.
Reglas WAF Esenciales
Navega a tu panel de Cloudflare: Security > WAF > Custom rules. Crearás estas reglas en orden de prioridad.
Regla 1: Bloquear xmlrpc.php
Esta es la regla de mayor impacto. xmlrpc.php representa la mayoría del tráfico de fuerza bruta en la mayoría de los sitios WordPress.
Expression:
(http.request.uri.path eq "/xmlrpc.php")
Action: Block
Si dependes de Jetpack o la app móvil de WordPress, cambia la acción a Managed Challenge en lugar de Block. Pero si puedes desactivar xmlrpc completamente, bloquéalo.
Regla 2: Challenge en wp-login.php
En lugar de bloquear la página de inicio de sesión por completo, usa un managed challenge para que los administradores legítimos puedan acceder mientras los bots son detenidos.
Expression:
(http.request.uri.path eq "/wp-login.php")
Action: Managed Challenge
Esto fuerza el challenge inteligente de Cloudflare (CAPTCHA o JS challenge) en cada solicitud a la página de inicio de sesión. Los bots automatizados fallan el challenge; los humanos reales lo pasan de forma transparente.
Regla 3: Restringir wp-admin por IP
Bloquea el área de administración a tu dirección IP. El detalle crítico aquí es excluir admin-ajax.php, que WordPress usa para llamadas AJAX del frontend (formularios de contacto, actualizaciones del carrito de WooCommerce, etc.).
Expression:
(http.request.uri.path contains "/wp-admin"
and not http.request.uri.path contains "admin-ajax.php"
and not ip.src in {203.0.113.50})
Action: Block
Reemplaza 203.0.113.50 con tu IP real. Puedes agregar múltiples IPs usando una lista: {203.0.113.50 198.51.100.25}.
Regla 4: Bloquear Inyección SQL y Recorrido de Directorios
Captura patrones de inyección comunes en la URI completa, incluyendo query strings.
Expression:
(http.request.uri contains "union select"
or http.request.uri contains "concat("
or http.request.uri contains "../"
or http.request.uri contains "eval("
or http.request.uri contains "<script"
or http.request.uri contains "etc/passwd")
Action: Block
Esta regla captura los payloads más frecuentes de SQLi y XSS. Los patrones cubren inyección basada en UNION, recorrido de directorios, inyección de JavaScript e intentos de inclusión de archivos locales.
Regla 5: Bloquear User Agents Maliciosos
Muchas herramientas de ataque usan user agents identificables. Combina el bloqueo de bots en una sola regla para aprovechar tus slots de reglas del plan gratuito.
Expression:
(http.request.uri.path contains "/wp-"
and (http.user_agent contains "sqlmap"
or http.user_agent contains "nikto"
or http.user_agent contains "wpscan"
or http.user_agent contains "masscan"
or http.user_agent eq ""))
Action: Block
Los user agents vacíos en endpoints de WordPress son casi siempre escáneres maliciosos. Esta regla los bloquea junto con las firmas de herramientas de ataque conocidas.
Características WAF: Gratuito vs Pro vs Business
| Característica | Gratuito | Pro ($20/mes) | Business ($200/mes) |
|---|---|---|---|
| Reglas WAF personalizadas | 5 | 20 | 100 |
| Conjuntos de reglas administradas (OWASP) | No | Sí | Sí |
| Reglas de limitación de velocidad | 1 | 10 | 50 |
| Gestión de bots | Básica | Mejorada | Avanzada |
| Páginas de error personalizadas | No | Sí | Sí |
| Analíticas WAF | Eventos básicos | Detallada | Completa con logs |
| Reglas de acceso por IP | Ilimitadas | Ilimitadas | Ilimitadas |
| Modificación de encabezados de respuesta | No | Sí | Sí |
Para la mayoría de los sitios WordPress, el plan gratuito con 5 reglas personalizadas bien diseñadas cubre el 90% del tráfico de ataque. Actualiza a Pro si necesitas conjuntos de reglas administradas OWASP o más slots de reglas.
Escenario del Mundo Real
Administras un sitio de comercio electrónico WordPress con WooCommerce que procesa 500 pedidos por día. Los logs de tu servidor muestran más de 1,200 intentos fallidos de inicio de sesión diarios en wp-login.php, tu xmlrpc.php recibe 8,000 solicitudes al día desde botnets, y has notado cadenas de inyección SQL apareciendo en tus logs de consultas. Tu proveedor de hosting te advierte sobre picos de CPU por procesar todas estas solicitudes maliciosas.
Después de activar las cinco reglas WAF anteriores, Cloudflare bloquea el 95% de este tráfico en el borde. El CPU de tu servidor baja un 40%, los tiempos de carga mejoran porque tus workers PHP no están ocupados procesando solicitudes de ataque, y tus costos de hosting se mantienen estables en lugar de escalar. El managed challenge en wp-login.php detiene el credential stuffing mientras tu equipo editorial inicia sesión sin problemas. La restricción por IP de wp-admin significa que incluso si un atacante obtiene credenciales, no puede acceder al panel desde su IP.
Limitación de Velocidad para WordPress
La limitación de velocidad agrega una dimensión temporal a tu protección. Navega a Security > WAF > Rate limiting rules.
Límite de Velocidad en Página de Inicio de Sesión
Expression:
(http.request.uri.path eq "/wp-login.php" and http.request.method eq "POST")
Rate: 5 requests per 10 seconds
Action: Block for 600 seconds (10 minutes)
Counting expression: Same as rule expression
Límite de Velocidad en REST API
Expression:
(http.request.uri.path contains "/wp-json/")
Rate: 30 requests per 10 seconds
Action: Managed Challenge
Esto previene la enumeración y abuso de la API mientras permite el uso normal de la REST API desde temas y plugins.
Solución de Problemas
admin-ajax.php debe ser excluido — WordPress usa admin-ajax.php para solicitudes AJAX del frontend incluso para visitantes no autenticados. Formularios de contacto, agregar al carrito de WooCommerce y scroll infinito usan este endpoint. Bloquearlo con una restricción por IP rompe todo tu frontend.
REST API de WooCommerce — si usas la REST API de WooCommerce para integraciones externas (proveedores de envío, sincronización de inventario, sistemas POS), asegúrate de que tu limitación de velocidad en /wp-json/ no bloquee estos servicios. Incluye sus IPs en la lista blanca o usa un umbral más alto.
Cron y tareas programadas — wp-cron.php es solicitado por las páginas cacheadas de Cloudflare. Si usas cron del servidor (recomendado), puedes bloquear el acceso externo a wp-cron.php con una regla WAF.
Actualizaciones de plugins y subida de archivos — algunos plugins hacen solicitudes a rutas de wp-admin durante las actualizaciones automáticas. Tu regla de restricción por IP maneja esto siempre que el servidor mismo no esté detrás de un servicio externo que cambie la IP de origen.
Precaución con el bloqueo por país — evita bloquear países enteros a menos que realmente no tengas usuarios allí. Los bloqueos a nivel de país pueden bloquear inadvertidamente rastreadores de motores de búsqueda que se enrutan a través de esos países, afectando tu SEO.
Prueba exhaustivamente — después de activar las reglas, abre una ventana de incógnito y prueba: visita la página de inicio, navega a una página de producto, envía un formulario de contacto e inicia sesión en wp-admin. Revisa Security > Events para detectar falsos positivos.
Resumen
- Bloquea
xmlrpc.phpcompletamente — es el endpoint más abusado de WordPress y la mayoría de los sitios no lo necesitan - Usa managed challenges en
wp-login.phppara detener bots mientras permites el acceso a administradores humanos - Restringe
wp-adminpor IP pero siempre excluyeadmin-ajax.phppara evitar romper la funcionalidad del frontend - Agrega coincidencia de patrones de inyección SQL y XSS para capturar payloads de inyección comunes en el borde
- Configura limitación de velocidad en endpoints de inicio de sesión y REST API para frenar intentos de fuerza bruta
- El plan gratuito de Cloudflare te da 5 reglas personalizadas — suficientes para cubrir la superficie de ataque crítica de WordPress
- Monitorea Security Events después de implementar las reglas y ajusta por falsos positivos
- Considera Cloudflare Access (Zero Trust) para escenarios con IP dinámica en lugar de listas blancas de IP