El archivo xmlrpc.php
de WordPress permite que aplicaciones externas, como la app móvil o Jetpack, se conecten a tu sitio. Sin embargo, también es uno de los vectores de ataque más utilizados por bots que intentan realizar ataques de fuerza bruta o de denegación de servicio (DoS).
En esta guía aprenderás a implantar un fragmento de código que protege xmlrpc.php
de ataques, sin bloquear su uso legítimo.
¿Qué es xmlrpc.php
y por qué puede ser un problema?
xmlrpc.php
es un archivo del núcleo de WordPress que habilita la comunicación remota con el sitio mediante el protocolo XML-RPC.
Se utiliza, por ejemplo, para:
- Publicar desde la app móvil de WordPress.
- Conectar Jetpack con tu sitio.
- Usar herramientas de gestión remota (IFTTT, Zapier, etc.).
El problema es que este mismo punto de entrada permite a los atacantes:
- Probar miles de combinaciones de usuario/contraseña (fuerza bruta).
- Enviar pings y pingbacks falsos (DDoS distribuido).
- Saturar recursos del servidor con llamadas masivas.
Estrategia: limitar el abuso, no bloquear el servicio
Muchos administradores optan por bloquear completamente xmlrpc.php
, pero eso rompe la compatibilidad con aplicaciones externas.
Una alternativa más elegante es implementar una capa de defensa lógica dentro de WordPress:
- Bloquea solo los métodos usados en ataques (
pingback.ping
,system.multicall
). - Limita la frecuencia de llamadas desde la misma IP.
- Devuelve códigos HTTP apropiados (403 o 429) cuando se detecta abuso.
Acceder al archivo functions.php
Puedes hacerlo de dos maneras:
- Desde el panel de administración:
Apariencia → Editor de archivos del tema → functions.php
- O, preferiblemente, usando un tema hijo o el plugin Code Snippets, para que las actualizaciones del tema no borren el código.
Añadir el siguiente fragmento de código:
add_action('xmlrpc_call', function($method) {
// Lista de métodos peligrosos (usados en ataques)
$blocked_methods = [
'system.multicall',
'pingback.ping',
'pingback.extensions.getPingbacks'
];
if (in_array($method, $blocked_methods)) {
header('HTTP/1.1 403 Forbidden');
exit;
}
// Límite de frecuencia: no más de 20 peticiones por IP en 1 minuto
$ip = $_SERVER['REMOTE_ADDR'];
$transient_key = 'xmlrpc_limit_' . md5($ip);
$attempts = get_transient($transient_key) ?: 0;
$attempts++;
set_transient($transient_key, $attempts, 60); // expira en 60 segundos
if ($attempts > 20) {
header('HTTP/1.1 429 Too Many Requests');
exit;
}
});
Guardar los cambios y probar
- Guarda el archivo
functions.php
o activa el snippet. - Desde otro navegador o terminal, prueba a acceder a:
https://tu-dominio.com/xmlrpc.php
- Si haces unas pocas peticiones, debería responder normalmente.
- Si haces muchas seguidas (más de 20 en menos de un minuto), devolverá HTTP 429 (Too Many Requests).
- Si intentas ejecutar un método de pingback, devolverá HTTP 403 (Forbidden).