XML-RPC è un protocollo di chiamata di procedura remota che WordPress supporta dai suoi primi anni. Il file xmlrpc.php si trova nella directory root della tua installazione WordPress e fornisce un'API che permette alle applicazioni esterne di comunicare con il tuo sito. Sebbene fosse genuinamente utile nel 2008 quando non esistevano alternative migliori, la REST API (introdotta in WordPress 4.7, dicembre 2016) l'ha sostituita completamente per i casi d'uso legittimi. Oggi, XML-RPC viene sfruttato principalmente dagli attaccanti per tentativi di login brute force e attacchi di amplificazione DDoS. Se non stai utilizzando Jetpack o uno strumento di pubblicazione mobile obsoleto, dovresti disabilitarlo.
La storia di XML-RPC in WordPress
Il supporto XML-RPC fa parte di WordPress dalla versione 1.5 (2005), ma era disabilitato per impostazione predefinita. I proprietari dei siti dovevano abilitarlo manualmente in Impostazioni se volevano usare client di blog desktop come Windows Live Writer o MarsEdit. In WordPress 3.5 (dicembre 2012), l'interfaccia XML-RPC è stata abilitata per impostazione predefinita e l'opzione per disabilitarla tramite l'interfaccia di amministrazione è stata rimossa. La motivazione era che le app mobili e i servizi esterni vi facevano sempre più affidamento. Tuttavia, questa decisione significava anche che ogni installazione WordPress ora aveva un endpoint API aperto che gli attaccanti potevano prendere di mira.
Con WordPress 4.7 (dicembre 2016), la REST API è diventata parte del core di WordPress. La REST API fornisce un'interfaccia moderna basata su JSON che è più flessibile, meglio documentata e più facile da proteggere rispetto a XML-RPC. L'app mobile di WordPress è passata da XML-RPC alla REST API nel 2019. A quel punto, l'unico grande servizio che ancora richiedeva XML-RPC era Jetpack, e anche Jetpack ha ridotto la sua dipendenza da XML-RPC nel tempo.
Come funziona l'attacco brute force system.multicall
L'aspetto più pericoloso di XML-RPC è il metodo system.multicall. I normali attacchi brute force alla pagina di login di WordPress provano una combinazione username/password per richiesta HTTP. Il rate limiting e plugin come Limit Login Attempts possono bloccare efficacemente questi attacchi perché ogni tentativo genera una richiesta separata.
Il system.multicall di XML-RPC cambia completamente l'equazione. Un attaccante può raggruppare centinaia o addirittura migliaia di tentativi di autenticazione wp.getUsersBlogs in una singola richiesta HTTP. Dalla prospettiva del server, questa appare come una richiesta. Dalla prospettiva dell'attaccante, hanno appena testato 500 password. I plugin di rate limiting per il login che operano a livello di applicazione spesso non rilevano questi tentativi perché vedono solo una richiesta in ingresso.
Ecco come appare un payload multicall brute force:
<?xml version="1.0"?>
<methodCall>
<methodName>system.multicall</methodName>
<params>
<param>
<value><array><data>
<value><struct>
<member>
<name>methodName</name>
<value><string>wp.getUsersBlogs</string></value>
</member>
<member>
<name>params</name>
<value><array><data>
<value><string>admin</string></value>
<value><string>password123</string></value>
</data></array></value>
</member>
</struct></value>
<!-- seguono centinaia di altri tentativi -->
</data></array></value>
</param>
</params>
</methodCall>Amplificazione DDoS tramite pingback
Il secondo grande vettore di attacco è la funzionalità di pingback XML-RPC. I pingback sono notifiche inviate tra siti WordPress quando un sito si collega a un altro. Gli attaccanti abusano di questo inviando richieste di pingback falsificate a migliaia di siti WordPress, tutte mirate a un singolo URL target. Ogni sito WordPress invia quindi una richiesta di verifica al target, trasformando effettivamente migliaia di installazioni WordPress in una botnet distributed denial-of-service (DDoS). Il server target viene sopraffatto da richieste in ingresso da siti WordPress legittimi, rendendolo difficile da bloccare.
Come testare se XML-RPC è attualmente abilitato
Prima di apportare modifiche, controlla se XML-RPC è attivo sul tuo sito. Puoi usare curl dalla riga di comando:
curl -X POST https://yoursite.com/xmlrpc.php -H "Content-Type: text/xml" -d '<?xml version="1.0"?><methodCall><methodName>system.listMethods</methodName></methodCall>'Se XML-RPC è abilitato, riceverai una risposta XML con tutti i metodi disponibili (di solito 80+ metodi). Se è disabilitato o bloccato, otterrai un errore 403 Forbidden, un errore di connessione rifiutata o un messaggio "XML-RPC server accepts POST requests only" (a seconda di come è stato disabilitato).
Controllare i log del server per gli attacchi XML-RPC
Prima di disabilitare XML-RPC, vale la pena controllare i tuoi access log per vedere se sei già sotto attacco. Cerca le richieste POST a xmlrpc.php:
# Apache access log
grep "xmlrpc.php" /var/log/apache2/access.log | tail -50
# Nginx access log
grep "xmlrpc.php" /var/log/nginx/access.log | tail -50
# Conta le richieste per IP
grep "xmlrpc.php" /var/log/apache2/access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head -20Se vedi centinaia o migliaia di richieste POST a xmlrpc.php da vari indirizzi IP, il tuo sito è attivamente preso di mira. Questo è estremamente comune ed è un altro motivo per disabilitare completamente l'endpoint.
Metodo 1: blocco a livello di server web (raccomandato)
Bloccare XML-RPC a livello di server web è l'approccio più efficace perché la richiesta viene rifiutata prima ancora che PHP venga caricato. Questo risparmia risorse del server ed è l'approccio da preferire rispetto al filtraggio a livello di PHP.
Apache (.htaccess)
Aggiungi questo al tuo file .htaccess nella directory root di WordPress:
# Blocca tutto l'accesso a xmlrpc.php
<Files xmlrpc.php>
Order deny,allow
Deny from all
</Files>Se devi consentire indirizzi IP specifici (ad esempio, se usi Jetpack), puoi aggiungere eccezioni:
<Files xmlrpc.php>
Order deny,allow
Deny from all
Allow from 122.248.245.244
Allow from 54.217.201.243
</Files>Nginx
Aggiungi questo all'interno del tuo server block nella configurazione Nginx:
location = /xmlrpc.php {
deny all;
access_log off;
log_not_found off;
return 403;
}Le direttive access_log off e log_not_found off impediscono che i tuoi file di log si riempiano di tentativi XML-RPC bloccati, che possono crescere fino a gigabyte su siti pesantemente presi di mira.
Metodo 2: disabilitare tramite filtro WordPress (livello PHP)
Se non puoi modificare i file di configurazione del server (comune con l'hosting condiviso), puoi disabilitare XML-RPC a livello PHP. Aggiungi questo al functions.php del tuo tema o, meglio ancora, a un must-use plugin personalizzato:
// Disabilita completamente XML-RPC
add_filter('xmlrpc_enabled', '__return_false');
// Rimuove il link di discovery XML-RPC dall'head HTML
remove_action('wp_head', 'rsd_link');
// Rimuove l'header HTTP X-Pingback
add_filter('wp_headers', function($headers) {
unset($headers['X-Pingback']);
return $headers;
});Importante: il filtro xmlrpc_enabled disabilita solo i metodi XML-RPC basati sull'autenticazione. Il file xmlrpc.php viene comunque caricato, PHP viene comunque eseguito e i metodi non autenticati (come i pingback) possono ancora funzionare. Questo è il motivo per cui il blocco a livello di server è preferibile. L'approccio del filtro consuma comunque risorse del server per elaborare la richiesta prima di rifiutarla.
Creare un must-use plugin (raccomandato rispetto a functions.php)
Invece di aggiungere codice a functions.php (che viene sovrascritto durante gli aggiornamenti del tema), crea un must-use plugin. Crea il file wp-content/mu-plugins/disable-xmlrpc.php:
<?php
/**
* Plugin Name: Disable XML-RPC
* Description: Disabilita completamente la funzionalità XML-RPC
*/
add_filter('xmlrpc_enabled', '__return_false');
remove_action('wp_head', 'rsd_link');
add_filter('wp_headers', function($headers) {
unset($headers['X-Pingback']);
return $headers;
});I must-use plugin vengono caricati prima dei plugin regolari e non possono essere disattivati accidentalmente tramite l'interfaccia di amministrazione.
Metodo 3: configurazione di un plugin di sicurezza
Se utilizzi un plugin di sicurezza come Wordfence, Sucuri o iThemes Security, questi offrono opzioni integrate per disabilitare XML-RPC:
- Wordfence: vai a Wordfence > All Options > Brute Force Protection. Il firewall limita automaticamente il rate dei tentativi di autenticazione XML-RPC. Per il blocco completo, usa il metodo a livello di server sopra descritto.
- iThemes Security: vai a Security > Settings > WordPress Tweaks. Abilita "Disable XML-RPC" per bloccarlo completamente, o seleziona "Disable Pingbacks" per bloccare solo il vettore di abuso pingback mantenendo funzionali altri metodi XML-RPC.
- Sucuri: il Sucuri Web Application Firewall (basato su cloud) può bloccare XML-RPC a livello di CDN, prima che le richieste raggiungano il tuo server.
Regole Cloudflare WAF per la protezione XML-RPC
Se utilizzi Cloudflare, puoi creare una regola WAF che blocca le richieste XML-RPC al perimetro, prima ancora che raggiungano il tuo server. Vai a Security > WAF > Custom Rules e crea una regola:
- Nome regola: Block XML-RPC
- Espressione:
(http.request.uri.path contains "/xmlrpc.php") - Azione: Block
Questo è il metodo di blocco più efficiente perché Cloudflare gestisce la richiesta sui suoi server edge. Il tuo server origin non vede mai il traffico. Se devi consentire Jetpack, aggiungi un'eccezione per gli intervalli IP di Automattic.
Configurazione fail2ban per il brute force XML-RPC
Se gestisci il tuo server (VPS o dedicato), puoi usare fail2ban per bannare automaticamente gli indirizzi IP che accedono ripetutamente a xmlrpc.php. Crea un file filtro in /etc/fail2ban/filter.d/wordpress-xmlrpc.conf:
[Definition]
failregex = ^<HOST> .* "POST .*xmlrpc.php.*" (200|403)
ignoreregex =Quindi aggiungi una jail in /etc/fail2ban/jail.local:
[wordpress-xmlrpc]
enabled = true
port = http,https
filter = wordpress-xmlrpc
logpath = /var/log/apache2/access.log
maxretry = 5
findtime = 60
bantime = 3600Questa configurazione banna qualsiasi indirizzo IP che fa più di 5 richieste a xmlrpc.php in 60 secondi e li blocca per un'ora. Regola i valori in base ai tuoi modelli di traffico.
XML-RPC vs. REST API: confronto sulla sicurezza
Capire perché la REST API è più sicura aiuta a spiegare perché XML-RPC dovrebbe essere ritirato:
- Autenticazione: la REST API supporta più metodi di autenticazione (cookie auth, application password, OAuth) e ha la verifica nonce integrata. XML-RPC invia le credenziali in chiaro all'interno del corpo XML ad ogni richiesta.
- Rate limiting: le richieste REST API possono essere rate-limited per endpoint. Il metodo multicall di XML-RPC rende inefficace il rate limiting per richiesta.
- Permessi: la REST API rispetta i controlli di capability di WordPress e fornisce callback di permesso granulari per ogni endpoint. XML-RPC ha controlli di accesso più grezzi.
- Validazione dell'input: gli endpoint REST API utilizzano la validazione dell'input basata su schema. XML-RPC fa affidamento sulle implementazioni dei singoli metodi per la validazione.
- Nessun equivalente multicall: la REST API non ha un endpoint batch che permette di raggruppare centinaia di tentativi di autenticazione in una richiesta.
Controlla se hai ancora bisogno di XML-RPC prima di disabilitarlo
Prima di disabilitare XML-RPC, verifica che nessuno dei tuoi servizi attivi lo richieda:
- Jetpack: alcune funzionalità di Jetpack comunicano ancora tramite XML-RPC. Se utilizzi Jetpack, testa il tuo sito dopo aver disabilitato XML-RPC. Se le funzionalità si rompono, potresti dover consentire gli indirizzi IP di Automattic o utilizzare il metodo allow-list a livello di server mostrato sopra.
- App mobile WordPress: le versioni attuali dell'app mobile WordPress utilizzano la REST API. Solo le versioni molto vecchie (precedenti al 2019) utilizzavano XML-RPC. Se la tua app funziona bene, non hai bisogno di XML-RPC.
- Integrazioni IFTTT o Zapier: alcune integrazioni obsolete con servizi di automazione utilizzavano XML-RPC. Controlla se le tue automazioni funzionano ancora dopo la disabilitazione.
- Windows Live Writer o altri editor desktop: questi strumenti obsoleti utilizzavano XML-RPC per la pubblicazione. Se ne stai ancora usando uno, considera di passare al block editor di WordPress o a un'alternativa basata su REST API.
Verificare che XML-RPC sia disabilitato
Dopo aver applicato il metodo scelto, verifica che XML-RPC sia effettivamente bloccato:
# Dovrebbe restituire 403 Forbidden o connection refused
curl -s -o /dev/null -w "%{http_code}" -X POST https://yoursite.com/xmlrpc.php -H "Content-Type: text/xml" -d '<?xml version="1.0"?><methodCall><methodName>system.listMethods</methodName></methodCall>'Se ottieni un codice di stato 403, XML-RPC è bloccato. Se ottieni ancora un 200, il tuo metodo di blocco non funziona correttamente. Controlla la tua configurazione e assicurati che il server sia stato riavviato (per Nginx) o che le modifiche a .htaccess vengano lette (per Apache, assicurati che AllowOverride sia abilitato).
Puoi anche eseguire una scansione InspectWP. La sezione di sicurezza rileva se XML-RPC è accessibile e lo segnala come potenziale rischio se risponde alle richieste.