O XML-RPC é um protocolo de chamada de procedimento remoto que o WordPress oferece desde os seus primeiros dias. O arquivo xmlrpc.php fica no diretório raiz do WordPress e fornece uma API para que aplicações externas se comuniquem com o seu site. Embora isso fosse genuinamente útil em 2008, quando não havia alternativas melhores, a REST API (introduzida no WordPress 4.7, em dezembro de 2016) substituiu-o completamente para casos de uso legítimos. Hoje, o XML-RPC é principalmente explorado por invasores para tentativas de login por força bruta e ataques de amplificação de DDoS. Se você não está usando o Jetpack ou uma ferramenta legada de publicação móvel, deveria desabilitá-lo.
A história do XML-RPC no WordPress
O suporte a XML-RPC faz parte do WordPress desde a versão 1.5 (2005), mas vinha desabilitado por padrão. Os proprietários de sites tinham que habilitá-lo manualmente nas Configurações se quisessem usar clientes de blog para desktop, como o Windows Live Writer ou o MarsEdit. No WordPress 3.5 (dezembro de 2012), a interface XML-RPC foi habilitada por padrão e a opção de desabilitá-la pela interface administrativa foi removida. O raciocínio era que aplicativos móveis e serviços externos dependiam cada vez mais dela. No entanto, essa decisão também significou que cada instalação WordPress agora tinha um endpoint de API aberto que invasores podiam alvejar.
Com o WordPress 4.7 (dezembro de 2016), a REST API tornou-se parte do núcleo do WordPress. A REST API oferece uma interface moderna baseada em JSON, que é mais flexível, melhor documentada e mais fácil de proteger do que o XML-RPC. O aplicativo móvel do WordPress mudou do XML-RPC para a REST API em 2019. A esta altura, o único serviço relevante que ainda exigia XML-RPC era o Jetpack, e mesmo o Jetpack tem reduzido sua dependência do XML-RPC ao longo do tempo.
Como funciona o ataque de força bruta system.multicall
O aspecto mais perigoso do XML-RPC é o método system.multicall. Ataques normais de força bruta contra a página de login do WordPress tentam uma combinação de usuário/senha por requisição HTTP. A limitação de taxa e plugins como o Limit Login Attempts podem bloquear esses ataques de forma eficaz, porque cada tentativa gera uma requisição separada.
O system.multicall do XML-RPC muda completamente a equação. Um invasor pode agrupar centenas ou até milhares de tentativas de autenticação wp.getUsersBlogs em uma única requisição HTTP. Da perspectiva do servidor, isso parece uma única requisição. Da perspectiva do invasor, eles acabaram de testar 500 senhas. Plugins de limitação de taxa de login que operam no nível da aplicação muitas vezes não detectam essas tentativas, porque veem apenas uma requisição entrando.
Veja como é uma carga útil de força bruta com multicall:
<?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>
<!-- centenas de tentativas a mais seguem -->
</data></array></value>
</param>
</params>
</methodCall>Amplificação de DDoS via pingbacks
O segundo grande vetor de ataque é o recurso de pingback do XML-RPC. Pingbacks são notificações enviadas entre sites WordPress quando um site faz link para outro. Invasores abusam disso enviando requisições de pingback forjadas a milhares de sites WordPress, todas apontando para uma única URL alvo. Cada site WordPress então envia uma requisição de verificação ao alvo, transformando efetivamente milhares de instalações WordPress em uma botnet de negação de serviço distribuída (DDoS). O servidor alvo é sobrecarregado com requisições de sites WordPress legítimos, dificultando o bloqueio.
Como testar se o XML-RPC está atualmente habilitado
Antes de fazer alterações, verifique se o XML-RPC está ativo em seu site. Você pode usar o curl pela linha de comando:
curl -X POST https://seusite.com/xmlrpc.php -H "Content-Type: text/xml" -d '<?xml version="1.0"?><methodCall><methodName>system.listMethods</methodName></methodCall>'Se o XML-RPC estiver habilitado, você receberá uma resposta XML listando todos os métodos disponíveis (normalmente mais de 80 métodos). Se estiver desabilitado ou bloqueado, você receberá um erro 403 Forbidden, um erro de conexão recusada ou uma mensagem "XML-RPC server accepts POST requests only" (dependendo de como foi desabilitado).
Verificando os logs do servidor em busca de ataques XML-RPC
Antes de desabilitar o XML-RPC, vale a pena verificar seus logs de acesso para ver se você já está sendo alvo. Procure por requisições POST para xmlrpc.php:
# Log de acesso do Apache
grep "xmlrpc.php" /var/log/apache2/access.log | tail -50
# Log de acesso do Nginx
grep "xmlrpc.php" /var/log/nginx/access.log | tail -50
# Contar requisições por IP
grep "xmlrpc.php" /var/log/apache2/access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head -20Se você ver centenas ou milhares de requisições POST para xmlrpc.php de vários endereços IP, seu site está sendo ativamente alvejado. Isso é extremamente comum, e é mais um motivo para desabilitar o endpoint inteiramente.
Método 1: Bloquear no nível do servidor web (recomendado)
Bloquear o XML-RPC no nível do servidor web é a abordagem mais eficaz, porque a requisição é rejeitada antes que o PHP sequer seja carregado. Isso economiza recursos do servidor e é a abordagem que você deve preferir em vez da filtragem no nível do PHP.
Apache (.htaccess)
Adicione isto ao seu arquivo .htaccess no diretório raiz do WordPress:
# Bloquear todo acesso ao xmlrpc.php
<Files xmlrpc.php>
Order deny,allow
Deny from all
</Files>Se você precisa permitir endereços IP específicos (por exemplo, se usa Jetpack), pode adicionar exceções:
<Files xmlrpc.php>
Order deny,allow
Deny from all
Allow from 122.248.245.244
Allow from 54.217.201.243
</Files>Nginx
Adicione isto dentro do seu bloco de servidor na configuração do Nginx:
location = /xmlrpc.php {
deny all;
access_log off;
log_not_found off;
return 403;
}As diretivas access_log off e log_not_found off impedem que seus arquivos de log se encham de tentativas bloqueadas de XML-RPC, que podem crescer para gigabytes em sites altamente alvejados.
Método 2: Desabilitar via filtro do WordPress (nível PHP)
Se você não consegue modificar arquivos de configuração do servidor (comum em hospedagem compartilhada), pode desabilitar o XML-RPC no nível do PHP. Adicione isto ao functions.php do seu tema ou, melhor ainda, a um plugin must-use personalizado:
// Desabilitar XML-RPC inteiramente
add_filter('xmlrpc_enabled', '__return_false');
// Remover o link de descoberta XML-RPC do head do HTML
remove_action('wp_head', 'rsd_link');
// Remover o cabeçalho HTTP X-Pingback
add_filter('wp_headers', function($headers) {
unset($headers['X-Pingback']);
return $headers;
});Importante: O filtro xmlrpc_enabled apenas desabilita os métodos XML-RPC baseados em autenticação. O arquivo xmlrpc.php ainda é carregado, o PHP ainda é executado e métodos não autenticados (como pingbacks) ainda podem funcionar. É por isso que bloquear no nível do servidor é preferível. A abordagem de filtro ainda consome recursos do servidor processando a requisição antes de finalmente rejeitá-la.
Criando um plugin must-use (recomendado em vez de functions.php)
Em vez de adicionar código ao functions.php (que é sobrescrito durante atualizações de tema), crie um plugin must-use. Crie o arquivo wp-content/mu-plugins/disable-xmlrpc.php:
<?php
/**
* Plugin Name: Disable XML-RPC
* Description: Desabilita completamente a funcionalidade 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;
});Plugins must-use são carregados antes dos plugins regulares e não podem ser acidentalmente desativados pela interface administrativa.
Método 3: Configuração de plugin de segurança
Se você usa um plugin de segurança como Wordfence, Sucuri ou iThemes Security, eles oferecem opções integradas para desabilitar o XML-RPC:
- Wordfence: Vá para Wordfence > All Options > Brute Force Protection. O firewall limita automaticamente a taxa de tentativas de autenticação XML-RPC. Para bloqueio completo, use o método de nível do servidor acima.
- iThemes Security: Vá para Security > Settings > WordPress Tweaks. Alterne "Disable XML-RPC" para bloqueá-lo completamente, ou selecione "Disable Pingbacks" para bloquear apenas o vetor de abuso de pingback, mantendo outros métodos XML-RPC funcionais.
- Sucuri: O Sucuri Web Application Firewall (baseado em nuvem) pode bloquear o XML-RPC no nível do CDN antes mesmo das requisições alcançarem o seu servidor.
Regras WAF do Cloudflare para proteção XML-RPC
Se você usa Cloudflare, pode criar uma regra WAF que bloqueia requisições XML-RPC na borda, antes que cheguem ao seu servidor. Vá para Security > WAF > Custom Rules e crie uma regra:
- Nome da regra: Block XML-RPC
- Expressão:
(http.request.uri.path contains "/xmlrpc.php") - Ação: Block
Este é o método de bloqueio mais eficiente, pois o Cloudflare lida com a requisição em seus servidores de borda. Seu servidor de origem nunca vê o tráfego. Se você precisa permitir Jetpack, adicione uma exceção para os intervalos de IP da Automattic.
Configuração do fail2ban para força bruta XML-RPC
Se você gerencia seu próprio servidor (VPS ou dedicado), pode usar o fail2ban para banir automaticamente endereços IP que repetidamente acessam o xmlrpc.php. Crie um arquivo de filtro em /etc/fail2ban/filter.d/wordpress-xmlrpc.conf:
[Definition]
failregex = ^<HOST> .* "POST .*xmlrpc.php.*" (200|403)
ignoreregex =Em seguida, adicione uma jail em /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 = 3600Esta configuração bane qualquer endereço IP que faça mais de 5 requisições ao xmlrpc.php em 60 segundos, bloqueando-o por uma hora. Ajuste os valores com base nos seus padrões de tráfego.
XML-RPC vs. REST API: comparação de segurança
Entender por que a REST API é mais segura ajuda a explicar por que o XML-RPC deveria ser aposentado:
- Autenticação: A REST API suporta múltiplos métodos de autenticação (cookie auth, application passwords, OAuth) e tem verificação de nonce integrada. O XML-RPC envia credenciais em texto puro dentro do corpo XML em cada requisição.
- Limitação de taxa: Requisições da REST API podem ter taxa limitada por endpoint. O método multicall do XML-RPC torna a limitação de taxa por requisição ineficaz.
- Permissões: A REST API respeita as verificações de capacidade do WordPress e fornece callbacks de permissão granulares para cada endpoint. O XML-RPC tem controle de acesso mais grosseiro.
- Validação de entrada: Endpoints da REST API usam validação de entrada baseada em esquema. O XML-RPC depende das implementações individuais dos métodos para validação.
- Sem equivalente ao multicall: A REST API não tem um endpoint em lote que permita agrupar centenas de tentativas de autenticação em uma única requisição.
Verifique se você ainda precisa do XML-RPC antes de desabilitar
Antes de desabilitar o XML-RPC, verifique se nenhum dos seus serviços ativos o requer:
- Jetpack: Alguns recursos do Jetpack ainda se comunicam via XML-RPC. Se você usa o Jetpack, teste seu site após desabilitar o XML-RPC. Se os recursos quebrarem, talvez seja necessário permitir os endereços IP da Automattic ou usar o método de allow-list no nível do servidor mostrado acima.
- Aplicativo móvel WordPress: As versões atuais do aplicativo móvel WordPress usam a REST API. Apenas versões muito antigas (antes de 2019) usavam XML-RPC. Se seu aplicativo funciona bem, você não precisa do XML-RPC.
- Integrações IFTTT ou Zapier: Algumas integrações antigas com serviços de automação usavam XML-RPC. Verifique se suas automações ainda funcionam após desabilitar.
- Windows Live Writer ou outros editores de desktop: Essas ferramentas legadas usavam XML-RPC para publicação. Se você ainda usa uma, considere mudar para o editor de blocos do WordPress ou uma alternativa baseada em REST API.
Verificando que o XML-RPC está desabilitado
Após aplicar o método escolhido, verifique se o XML-RPC está realmente bloqueado:
# Deve retornar 403 Forbidden ou conexão recusada
curl -s -o /dev/null -w "%{http_code}" -X POST https://seusite.com/xmlrpc.php -H "Content-Type: text/xml" -d '<?xml version="1.0"?><methodCall><methodName>system.listMethods</methodName></methodCall>'Se você obtiver um código de status 403, o XML-RPC está bloqueado. Se ainda obtiver 200, seu método de bloqueio não está funcionando corretamente. Verifique sua configuração e certifique-se de que o servidor foi reiniciado (para Nginx) ou que as alterações no .htaccess estão sendo lidas (para Apache, certifique-se de que o AllowOverride está habilitado).
Você também pode executar uma varredura do InspectWP. A seção de segurança detecta se o XML-RPC está acessível e o sinaliza como um risco potencial se ele responder a requisições.