secaudit.eu
Proteção

Proteção contra força bruta no WordPress: o que um plugin trava

Proteção contra força bruta no WordPress por camadas: limitação de inícios de sessão, multicall do XML-RPC, enumeração na API REST e porque um plugin não trava um DDoS.

Por , AngelForce OÜ 9 min de leitura

Também em: English Deutsch Français Español Italiano Polski Türkçe

Um plugin de segurança é bom a atrasar a adivinhação de palavras-passe. Não consegue travar uma inundação de tráfego. A proteção contra força bruta no WordPress e a proteção contra DDoS são problemas diferentes, e cada um resolve-se numa camada própria: as contas, o próprio WordPress, o servidor web e a borda da rede, à frente de tudo.

Este artigo percorre os ataques que costuma encontrar nos registos: inícios de sessão falhados em wp-login.php, rajadas de pedidos a xmlrpc.php, enumeração de utilizadores através da API REST e picos de tráfego. Para cada um, indica a camada que o consegue realmente travar. Cada medida inclui também uma linha sobre aquilo que não faz.

A proteção contra força bruta no WordPress funciona por camadas

O tráfego chega da internet e atravessa várias camadas até chegar aos seus dados. Quanto mais longe do servidor um pedido for travado, menos custa. Um pedido rejeitado numa CDN nunca chega ao seu servidor. Um pedido rejeitado por um plugin do WordPress já ocupou uma ligação de rede, um processo do servidor web e um worker de PHP.

Diagrama de camadas: CDN ou firewall de borda, servidor web, plugin do WordPress e contas
Onde cada ataque é travado: inundações na borda, abuso do início de sessão no WordPress e na conta

Um mapeamento aproximado:

AtaqueMelhor camada
Adivinhação de palavras-passeConta (2FA) + plugin
Multicall do XML-RPCPlugin ou servidor web
Enumeração REST, scrapingPlugin + borda
Inundação volumétricaCDN / borda, alojamento

Limitação de inícios de sessão: atrasar a adivinhação em wp-login.php

A limitação conta as tentativas falhadas e responde com atrasos crescentes, com o bloqueio temporário da origem ou com um desafio (CAPTCHA, por exemplo). Por predefinição, o WordPress não tem qualquer limite. Um atacante pode testar palavras-passe em wp-login.php à velocidade a que o servidor responder.

Os limites por IP funcionam bem contra uma única origem ruidosa. Funcionam pior contra uma botnet que reparte as tentativas por milhares de endereços, cada um abaixo do seu limite. Por isso, convém ter também limites por nome de utilizador. Vinte falhas contra a conta «admin» vindas de vinte IP diferentes continuam a ser um padrão.

Os limites por utilizador trazem uma armadilha própria. Um bloqueio rígido permite que qualquer pessoa deixe o seu administrador real à porta, bastando falhar de propósito. Atrasos crescentes ou um desafio são mais seguros do que o bloqueio total.

Duas coisas decidem se a limitação ajuda ou prejudica:

  • O IP do cliente. Atrás de uma CDN ou de um proxy inverso, todos os pedidos podem parecer vir do endereço do proxy. Um plugin que só veja esse endereço vai limitar todos os seus visitantes ao mesmo tempo. O erro oposto é igualmente mau: se o plugin confiar no cabeçalho X-Forwarded-For venha de onde vier, os atacantes inventam um IP novo em cada pedido e nunca são bloqueados. Configure o plugin, ou o módulo de IP real do servidor web, para aceitar cabeçalhos reencaminhados apenas dos intervalos de IP do seu proxy.
  • O seu caminho de regresso. Coloque na lista de permissões o IP do escritório, se for fixo, e conheça o procedimento de recuperação antes de precisar dele.

O que a limitação não faz: não torna segura uma palavra-passe fraca ou reutilizada. Uma palavra-passe de uma lista de dados divulgados em fugas pode funcionar à primeira. A solução de fundo é um segundo fator em todas as contas com privilégios elevados, configurado como se descreve em autenticação de dois fatores para administradores do WordPress.

XML-RPC: porque o system.multicall transforma um pedido em muitas tentativas

O xmlrpc.php está ativo por predefinição no WordPress. É uma interface antiga de publicação remota e um dos seus métodos, system.multicall, executa muitas chamadas dentro de um único pedido HTTP. Um atacante consegue meter uma longa lista de tentativas de utilizador/palavra-passe num só POST.

Isto contorna a proteção que apenas vigia o wp-login.php ou conta pedidos. Uma linha no registo pode significar centenas de tentativas. Certifique-se de que a sua limitação conta também as falhas de autenticação via XML-RPC, ou elimine por completo esta superfície de ataque.

Os pingbacks do XML-RPC também podem ser abusados para fazer o seu site enviar pedidos a terceiros. É mais um motivo para os desligar, se nada precisar deles.

Antes de desativar o XML-RPC: veja o que ainda o utiliza

Algumas ferramentas legítimas continuam a comunicar com o xmlrpc.php. Entre os candidatos estão ferramentas mais antigas de blogging no computador e de publicação remota, configurações antigas de aplicações móveis, alguns plugins conectores e integrações construídas há anos. A ligação do Jetpack baseou-se historicamente no XML-RPC, pelo que, se o utiliza, consulte a documentação atual.

Comece por analisar os registos de acesso. Num servidor Apache ou nginx típico, com o formato de registo combined:

# Que IPs enviam pedidos POST para xmlrpc.php?
grep "POST /xmlrpc.php" /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head

# Que user agents?
awk -F'"' '/POST \/xmlrpc.php/ {print $6}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head

Ajuste o caminho ao seu servidor (por exemplo, /var/log/apache2/access.log) e inclua os registos rodados. Milhares de pedidos vindos de IP rotativos, com user agents genéricos, são ataques. Meia dúzia de pedidos do IP de um serviço conhecido provavelmente pertence a uma integração; pergunte à agência ou ao fornecedor antes de a cortar.

Tem duas opções:

  1. **O filtro xmlrpc_enabled.** Desativa os métodos XML-RPC que exigem autenticação, o que impede a adivinhação de palavras-passe por esta via. Os métodos sem autenticação, como os pingbacks, continuam a funcionar. Consulte a referência para programadores do WordPress.
  2. Bloquear o ficheiro ao nível do servidor. Isto trava tudo e o PHP nem chega a executar para estes pedidos.
<Files xmlrpc.php>
    Require all denied
</Files>
location = /xmlrpc.php {
    deny all;
}

Depois da alteração, teste a publicação, a aplicação e qualquer serviço ligado. Registe o que alterou e porquê, para que a pessoa seguinte não o «corrija» de volta.

Enumeração de utilizadores na API REST e limitação de pedidos anónimos

/wp-json/wp/v2/users lista os utilizadores que publicaram conteúdo, incluindo os respetivos slugs. /?author=1 redireciona para um arquivo de autor que revela o slug no URL. Os slugs coincidem muitas vezes com o nome de utilizador de início de sessão, o que entrega ao atacante metade das credenciais.

Restringir o endpoint de utilizadores para visitantes anónimos e bloquear as pesquisas de autores reduz o ruído de reconhecimento. Ainda assim, os nomes de utilizador não são segredos. Escondê-los não é, por si só, um controlo de segurança.

Limitar os pedidos REST anónimos ajuda contra o scraping e as sondagens automáticas. Aplique o limite apenas ao tráfego anónimo e teste depois. O editor de blocos usa a API REST para os utilizadores com sessão iniciada, e as integrações autenticam-se com Palavras-passe de Aplicação (no núcleo desde o WordPress 5.6). Um limite que as apanhe estraga a edição ou uma tarefa de sincronização de formas difíceis de localizar.

O que não faz: a limitação de pedidos não corrige um endpoint REST vulnerável num plugin. Só atrasa as tentativas de o explorar.

Porque um plugin não consegue travar um ataque DDoS

Um plugin é código PHP. Só corre depois de o pedido ter atravessado a rede, sido aceite pelo servidor web e entregue a um worker de PHP. Uma inundação volumétrica satura a sua largura de banda, os limites de ligações ou o conjunto de workers de PHP muito antes desse ponto. Mesmo que o plugin rejeite cada pedido em um milissegundo, cada rejeição ocupa um worker, e um servidor só tem um número limitado deles.

As inundações na camada aplicacional são diferentes. São muitos pedidos dispendiosos mas de aspeto legítimo, como pesquisas ou páginas sem cache. Aqui, limitar os pedidos mais perto da aplicação ajuda um pouco, mas só até à capacidade do servidor.

O alerta de picos de tráfego de um plugin é útil porque avisa que algo se passa. Não absorve nada. Qualquer produto que chame «proteção DDoS» a um plugin do WordPress está a prometer demais.

O que faz uma CDN ou firewall de borda, e o que o servidor web pode acrescentar

Uma CDN ou firewall de borda fica à frente do seu alojamento, numa rede muito maior do que a sua. Consegue absorver e filtrar inundações, aplicar limites e regras de bots antes de o tráfego chegar até si, servir páginas em cache quando o servidor está aflito e lançar desafios aos pedidos a wp-login.php e xmlrpc.php. Depois de a ter montado, feche a origem: permita na firewall do servidor apenas os intervalos de IP da CDN. Caso contrário, os atacantes contornam a CDN e vão diretamente ao endereço real do servidor.

No servidor web, o [módulo limit_req](https://nginx.org/en/docs/http/ngx_http_limit_req_module.html) do nginx consegue limitar as tentativas de início de sessão antes de o PHP arrancar. Atrás de uma CDN ou proxy inverso, configure primeiro o módulo de IP real (confiando apenas nos intervalos do seu proxy); caso contrário, $binary_remote_addr é o endereço do proxy e todos os visitantes partilham o mesmo limite:

# http context
limit_req_zone $binary_remote_addr zone=wplogin:10m rate=5r/m;

# server context
location = /wp-login.php {
    limit_req zone=wplogin burst=5 nodelay;
    # keep your existing fastcgi_pass / include lines here
}

O fail2ban segue outra abordagem. Lê os registos e bane os reincidentes na firewall, o que é mais barato do que responder-lhes em PHP. Atrás de uma CDN isto não funciona tal como está: a firewall do servidor só vê os endereços da CDN, pelo que os bloqueios têm de ser feitos na própria CDN (ou através da sua API). Em alojamento gerido, pergunte que proteção de rede o fornecedor já inclui.

Aqui também há limites. Uma firewall de borda não corrige palavras-passe fracas nem plugins vulneráveis. Também não ajuda quanto ao que um atacante pode fazer depois de iniciar sessão, tema de desativar o editor de ficheiros do WordPress.

Uma ordem de implementação para PME da UE

  1. Palavras-passe fortes e únicas e 2FA para todos os administradores e editores.
  2. Limitação de inícios de sessão com limites por IP e por utilizador, deteção correta do IP do cliente e um procedimento de recuperação testado.
  3. A decisão sobre o XML-RPC: analise os registos e depois use o filtro ou um bloqueio no servidor.
  4. Restrições à enumeração de utilizadores e limites aos pedidos REST anónimos.
  5. Uma CDN ou firewall de borda com a origem fechada, nos sites em que a indisponibilidade custa dinheiro.

Isto conta também para a conformidade. O artigo 32.º, n.º 1, alínea b), do RGPD exige a confidencialidade, integridade, disponibilidade e resiliência permanentes dos sistemas (RGPD no EUR-Lex). Para as entidades abrangidas pela Diretiva NIS2, o artigo 21.º, n.º 2, alínea j), inclui a autenticação multifator entre as medidas mínimas (NIS2 no EUR-Lex). Consulte a lei nacional de transposição da NIS2 no seu país para os pormenores.

O plugin Security Audit & Compliance, da secaudit.eu, oferece limitação de inícios de sessão, desativação do XML-RPC, limitação de pedidos REST anónimos e alertas de picos de tráfego. Não é proteção contra DDoS; para isso, use uma CDN ou firewall de borda. → secaudit.eu

Próximo passo: percorra o resto da lista de verificação de segurança do WordPress. Se os seus registos já mostram inícios de sessão bem-sucedidos que não reconhece, vá antes para os sinais de um site comprometido.

FAQ

Desativar o XML-RPC vai afetar o Jetpack ou a minha aplicação?

Pode afetar. Procure nos registos clientes XML-RPC legítimos e consulte a documentação atual do fornecedor. O filtro xmlrpc_enabled é a opção mais suave; o bloqueio ao nível do servidor é a mais estrita. Teste depois de qualquer uma das alterações.

Mudar o nome de wp-login.php trava a força bruta?

Reduz o ruído dos bots simples, mas não é um controlo de segurança. Os atacantes continuam a encontrar a página de início de sessão ou a recorrer ao XML-RPC. Use também limitação e 2FA.

O meu plugin de segurança chega durante um DDoS?

Não. Contacte o fornecedor de alojamento ou a CDN. É a filtragem na borda e a cache que mantêm o site acessível.

A limitação pode deixar-me sem acesso?

Pode, se o IP do cliente for detetado incorretamente ou se errar repetidamente a palavra-passe. Coloque o seu IP na lista de permissões e mantenha à mão o acesso por WP-CLI ou SFTP para desativar o plugin.

Este artigo é informação geral e não constitui aconselhamento jurídico.

Verifique o seu site

O Security Audit & Compliance é o plugin WordPress da secaudit.eu: procura malware, spam oculto, ficheiros do núcleo alterados e código vulnerável, e associa as conclusões ao art. 32.º do RGPD, ao art. 21.º da NIS2 e ao OWASP Top 10.

Ver o que o plugin verifica
Melike Görel

Melike Görel escreve os guias da secaudit.eu sobre segurança do WordPress e conformidade com as regras da UE para a AngelForce OÜ, a empresa de software de Taline responsável pela secaudit.eu.

Elaborado com apoio de IA e verificado antes da publicação. Este artigo é informação geral e não constitui aconselhamento jurídico.