Como corrigir a enumeracao de usuários no WordPress com All in One Security
O que é user enumeration no WordPress?
User enumeration no WordPress, ou enumeracao de usuários, e a técnica em que um atacante coleta os nomes de login validos do site sem precisar de senha. O WordPress, por padrão, deixa esses nomes vazarem por três caminhos: a REST API pública em /wp-json/wp/v2/users, que devolve a lista de autores em JSON; a query de autor /?author=1, que redireciona para a URL do perfil expondo o slug do usuário; e o XML-RPC, que aceita chamadas como wp.getUsersBlogs para validar logins. Com a lista de logins em maos, o atacante so precisa adivinhar a senha.
O All in One Security (AIOS), da equipe TeamUpdraft, trata a enumeracao como o primeiro elo da cadeia de um ataque de forca bruta. Por isso o plugin reune, no mesmo painel, o bloqueio da REST API de usuários, o controle do XML-RPC e a prevencao de forca bruta baseada em cookie, que esconde a própria página de login. Fechar a enumeracao reduz a superficie de ataque: sem a lista de usuários, o invasor perde o alvo e a tentativa de adivinhar senhas fica muito mais cara.
Como identificar
- Ao acessar ‘https://seusite.com/wp-json/wp/v2/users’ o navegador devolve um JSON com ‘id’, ‘name’ e ‘slug’ de cada autor, revelando os logins.
- Abrir ‘https://seusite.com/?author=1’ redireciona para ‘/author/nomedousuario/’, expondo o slug de login no endereco.
- Os relatórios do AIOS em ‘Logins falhos’ e ‘404 detection’ mostram tentativas repetidas de login com os nomes de usuário reais do site.
- Scanners externos de segurança apontam o aviso ‘Username enumeration is possible’ ou ‘User registration disclosure’.
- Picos de requisicoes em ‘wp-login.php’ e em ‘xmlrpc.php’ nos logs do servidor logo após varreduras ao endpoint de usuários.
Como prevenir
- Mantenha o All in One Security ativo com a forca bruta baseada em cookie ligada, para que a página de login nunca fique exposta a quem já conhece os nomes de usuário.
- Nunca use o login como nome de exibicao público: defina sempre um apelido distinto em cada perfil de usuário com permissão de publicar.
- Revise periodicamente os endpoints ‘/wp-json/wp/v2/users’ e ‘/?author=1’ em janela anonima depois de atualizar tema ou plugins, pois uma atualização pode reabrir o vazamento.
- Desative o XML-RPC sempre que nenhum aplicativo externo depender dele, eliminando um vetor de validação de login em massa.
Causa
- O endpoint REST '/wp-json/wp/v2/users' esta acessivel sem autenticacao e lista todos os autores com 'slug', que e exatamente o nome usado no login.
- A query de autor '/?author=N' do WordPress redireciona para '/author/{slug}/', revelando o login de cada usuário por forca da numeracao sequencial de IDs.
- O XML-RPC ('/xmlrpc.php') esta habilitado e aceita o método 'wp.getUsersBlogs', que confirma se um par usuário e senha e valido e ainda permite amplificar tentativas por chamada.
- O nome de exibicao (display name) do usuário administrador foi deixado igual ao nome de login, entao o slug do autor entrega a credencial diretamente.
- A proteção de forca bruta do AIOS esta desativada, deixando a página 'wp-login.php' pública para que o atacante teste as senhas dos usuários já enumerados.
Como resolver
- Confirme que o site esta enumeravel: Antes de mexer em qualquer ajuste, comprove o vazamento abrindo os dois endpoints num navegador anonimo. Se a REST API devolver a lista de autores e a query de autor redirecionar para o slug, a enumeracao esta ativa e os passos seguintes vao fechar cada vetor.
https://seusite.com/wp-json/wp/v2/users https://seusite.com/?author=1 - Ative a prevencao de forca bruta no AIOS: No painel do All in One Security, ligue a proteção de forca bruta baseada em cookie. Conforme a documentação oficial, ela esconde a 'wp-login.php' atras de uma URL secreta e redireciona quem não tem o cookie, cortando o teste de senhas sobre os logins que vazaram.
Painel WP -> WP Security -> Firewall -> Brute Force Marque 'Enable Brute Force Attack Prevention' Defina uma 'Secret Word' para a URL secreta de login e salve - Bloqueie a enumeracao pela REST API e pela query de autor: Use o snippet PHP da seção de código para barrar o endpoint '/wp/v2/users' para visitantes não logados e abortar a query '?author=N'. Isso impede que a lista de autores e o slug de login sejam servidos publicamente, fechando os dois vetores principais.
Painel WP -> Aparencia -> Editor de Arquivos do Tema -> functions.php do tema filho Cole o snippet da seção 'Código' ao final do arquivo Salve e recarregue '/wp-json/wp/v2/users' para confirmar o retorno 'rest_user_cannot_view' - Desabilite o XML-RPC se não for usado: No AIOS, desligue o acesso ao XML-RPC para eliminar o método 'wp.getUsersBlogs', muito usado para validar logins e amplificar tentativas. So mantenha ativo se algum app externo (como o app oficial do WordPress ou o Jetpack) realmente depender dele.
Painel WP -> WP Security -> Firewall -> Basic Firewall Rules Marque 'Completely Block Access To XMLRPC' Clique em 'Save Basic Firewall Settings' - Separe o nome de login do nome de exibicao: Mesmo com os endpoints fechados, ajuste o perfil do administrador para que o nome público nunca seja o login. Defina o 'Apelido' e o campo 'Exibir este nome publicamente' com um valor diferente do usuário de acesso, removendo a última pista de credencial.
Painel WP -> Usuários -> Perfil -> campo 'Apelido (obrigatório)' Defina o 'Apelido' diferente do nome de login Em 'Exibir este nome publicamente', selecione o apelido e salve o perfil
<?php
// Bloqueia a enumeracao de usuarios pela REST API e pela query de autor.
// 1) Esconde o endpoint /wp-json/wp/v2/users de visitantes nao logados.
add_filter( 'rest_endpoints', 'full_block_users_rest_endpoint' );
function full_block_users_rest_endpoint( $endpoints ) {
if ( is_user_logged_in() ) {
return $endpoints;
}
if ( isset( $endpoints['/wp/v2/users'] ) ) {
unset( $endpoints['/wp/v2/users'] );
}
if ( isset( $endpoints['/wp/v2/users/(?P<id>[d]+)'] ) ) {
unset( $endpoints['/wp/v2/users/(?P<id>[d]+)'] );
}
return $endpoints;
}
// 2) Aborta a query /?author=N que vaza o slug de login.
add_action( 'template_redirect', 'full_block_author_query' );
function full_block_author_query() {
if ( is_admin() ) {
return;
}
if ( ! empty( $_GET['author'] ) && is_numeric( $_GET['author'] ) ) {
wp_safe_redirect( home_url(), 301 );
exit;
}
}














