Contents
Por qué bloquear xmlrpc.php parcialmente (y no desactivarlo por completo)
El archivo xmlrpc.php de WordPress implementa el protocolo XML-RPC y permite a aplicaciones externas (apps móviles, clientes de escritorio, Jetpack histórico, algunos plugins y servicios de terceros) ejecutar métodos remotos en tu sitio —por ejemplo, publicar entradas, subir archivos o listar blogs. Sin embargo xmlrpc.php es también un vector común de abuso:
- Fuerza bruta contra credenciales mediante llamadas remotas (wp.getUsersBlogs, wp.newPost, etc.).
- Amplificación y DDoS con métodos como system.multicall.
- Abuso de pingbacks (pingback.ping) para realizar ataques de reflexión o spam.
- Exploración automatizada que consume recursos y genera peticiones masivas.
Por eso la estrategia más recomendable es: mantener xmlrpc.php activo cuando realmente lo necesitas, pero bloquear o limitar los métodos peligrosos y no necesarios. Así se evitan roturas en funcionalidades legítimas y se reduce la superficie de ataque.
Estrategia general
- Identificar qué clientes / plugins necesitan xmlrpc (apps móviles, procesos de publicación remota, integraciones externas).
- Hacer copia de seguridad del sitio y del fichero functions.php o usar mu-plugins para no perder cambios en actualizaciones.
- Aplicar un filtrado por método (whitelist preferible) dentro de WordPress para permitir solo lo imprescindible.
- Complementar con reglas a nivel de servidor (bloqueo por IP, limitación de tasa) si procede.
- Monitorizar logs y ajustar la lista de métodos permitidos según el comportamiento real.
Ventajas del filtrado por método dentro de WordPress
- Permite bloquear llamadas peligrosas (pingback, system.multicall) sin cerrar por completo xmlrpc.php.
- Es configurable y se puede mantener como mu-plugin para que sobreviva actualizaciones.
- Ofrece control granular (lista blanca) y registro de intentos si se añade logging.
Solución recomendada (en WordPress): plugin MU que haga whitelist de métodos
Crear un mu-plugin (archivo PHP colocado en wp-content/mu-plugins/) que filtre los métodos XML-RPC mediante el filtro xmlrpc_methods y, adicionalmente, haga una comprobación temprana del cuerpo de la petición para registrar y bloquear llamadas no permitidas antes de que consuman recursos.
Archivo MU-PLUGIN: ejemplo práctico
lt?php / Plugin Name: XML-RPC Method Whitelist Description: Bloquea métodos XML-RPC no permitidos y registra intentos. Version: 1.0 / add_filter(xmlrpc_methods, xmlrpc_methods_whitelist) function xmlrpc_methods_whitelist(methods) { // Lista blanca: AJUSTAR según las necesidades reales de tu sitio. allowed = array( wp.getUsersBlogs, // usado por apps para autenticación / listar blogs wp.getPosts, wp.getPost, wp.newPost, wp.editPost, wp.deletePost, wp.uploadFile ) // Eliminar todo lo que no esté en la lista blanca foreach (methods as name => func) { if (!in_array(name, allowed, true)) { unset(methods[name]) } } // Refuerzo explícito: bloquear pingbacks y system.multicall aunque no estén en la lista if (isset(methods[pingback.ping])) unset(methods[pingback.ping]) if (isset(methods[system.multicall])) unset(methods[system.multicall]) return methods } // Comprobación temprana y registro: inspecciona el cuerpo XML y bloquea llamadas no permitidas add_action(init, xmlrpc_early_block_and_log, 1) function xmlrpc_early_block_and_log() { if (_SERVER[REQUEST_METHOD] !== POST) return if (strpos(_SERVER[REQUEST_URI], xmlrpc.php) === false !isset(_GET[xmlrpc])) return body = file_get_contents(php://input) if (! body) return if (preg_match(#([^<] ) #, body, m)) { method = trim(m[1]) // Debe coincidir con la misma lista blanca usada arriba allowed = array( wp.getUsersBlogs, wp.getPosts, wp.getPost, wp.newPost, wp.editPost, wp.deletePost, wp.uploadFile ) if (!in_array(method, allowed, true)) { // Registrar intento error_log(sprintf([xmlrpc] Bloqueado método %s desde %s, method, _SERVER[REMOTE_ADDR])) // devolver 403 rápidamente header(HTTP/1.1 403 Forbidden) echo Forbidden exit } } }
Notas sobre el mu-plugin
- Colocarlo en wp-content/mu-plugins/ (crear la carpeta si no existe). Los mu-plugins se cargan siempre.
- Ajusta la lista allowed con los métodos que realmente necesites. Si alguna app deja de funcionar, añade el método requerido y vuelve a probar.
- La función registra intentos bloqueados en el log de PHP/servidor para diagnóstico. Revisa error_log o el log del servidor.
Alternativas / complementos a nivel de servidor
Además del mu-plugin, es buena idea añadir reglas a nivel de servidor para limitar ataques por volumen o bloquear xmlrpc.php por IP cuando proceda.
Apache (.htaccess) — ejemplo: permitir xmlrpc.php solo desde IPs concretas
# Para Apache 2.4 ltFiles xmlrpc.phpgt Require all denied Require ip 203.0.113.5 # IP admin o servicio autorizado Require ip 198.51.100.0/24 # rango de confianza (si aplica) lt/Filesgt
Este enfoque es adecuado cuando solo unas IPs fijas necesitan acceder (por ejemplo, un servidor de integración). Para usuarios móviles o servicios dinámicos no será práctico.
Nginx — ejemplo: permitir sólo ciertas IPs
location = /xmlrpc.php { allow 203.0.113.5 allow 198.51.100.0/24 deny all include fastcgi_params fastcgi_pass unix:/run/php/php7.4-fpm.sock # ajustar según la configuración }
Nginx con inspección del cuerpo (opcional, requiere ngx_lua)
Si quieres permitir sólo llamadas a métodos concretos desde toda la red, una opción avanzada es usar ngx_lua para inspeccionar el XML y permitir o denegar según el methodName. Requiere que tu Nginx tenga ngx_http_lua_module.
location = /xmlrpc.php { content_by_lua_block { ngx.req.read_body() local body = ngx.req.get_body_data() or local method = body:match(([^<] ) ) local allowed = { [wp.getUsersBlogs] = true, [wp.newPost] = true } if not method or not allowed[method] then ngx.status = ngx.HTTP_FORBIDDEN ngx.say(Forbidden) return ngx.exit(ngx.HTTP_FORBIDDEN) end -- Si pasa, pasar al backend PHP-FPM ngx.exec(@php_fpm) } }
Cómo probar y validar cambios (probar antes de desplegar en producción)
- Hacer copia completa del sitio (archivos BD).
- En staging aplicar el mu-plugin y las reglas de servidor.
- Probar con curl una llamada válida (ejemplo wp.getUsersBlogs):
wp.getUsersBlogs usuario contraseña
curl -v -H Content-Type: text/xml --datahttps://tusitio.example.com/xmlrpc.php wp.getUsersBlogs usuario contraseña
– Si el método está en la lista blanca, recibirás respuesta XML válida o fallo de credenciales si los datos son incorrectos.
– Si el método está bloqueado, recibirás 403 (en el caso del mu-plugin que envía 403) o un error que indique que el método no existe.
Métodos que conviene bloquear por defecto
Estos métodos son problemáticos para la seguridad o poco necesarios en la mayoría de instalaciones:
- pingback.ping — genera spam y puede usarse para ataques de reflexión.
- system.multicall — permite agrupar llamadas y amplificar intentos de brute force.
- system.listMethods — facilita el reconocimiento de métodos disponibles.
Registro, detección y mitigación adicional
- Revisa los logs (error_log, access_log) y busca POST a /xmlrpc.php. Registra IPs repetidas.
- Usa plugins de seguridad (Wordfence, iThemes Security) que ofrecen reglas específicas para xmlrpc y bloqueo de fuerza bruta.
- Considera Fail2Ban para bloquear IPs con muchas peticiones a xmlrpc.php — crea un filtro que detecte muchas POSTs en corto periodo.
- Si no necesitas xmlrpc en absoluto, es más simple desactivarlo pero antes revisa compatibilidad con apps y servicios.
Checklist final antes de dejarlo en producción
- Hacer backup completo.
- Desplegar mu-plugin en staging y confirmar que las apps necesarias funcionan.
- Comprobar que pingbacks y system.multicall están bloqueados.
- Implementar reglas a nivel de servidor si aplica (IP, rate-limiting).
- Poner alertas en logs para detectar intentos de abuso y ajustar la whitelist si algún servicio legítimo queda bloqueado.
- Revisar periódicamente la lista de métodos permitidos según nuevas necesidades.
Conclusión
Bloquear xmlrpc.php parcialmente es la mejor práctica cuando necesitas mantener funcionalidades remotas pero quieres reducir el riesgo. La combinación de un filtro por métodos dentro de WordPress (lista blanca vía xmlrpc_methods o comprobación temprana del body) junto con controles a nivel de servidor (IP, rate limiting, fail2ban) ofrece un balance entre seguridad y funcionalidad. Ajusta la lista blanca a tus clientes reales, registra intentos bloqueados y monitoriza para afinar la configuración.
|
Acepto donaciones de BAT's mediante el navegador Brave 🙂 |