Antes de testar uma falha, um robô precisa saber com o que está falando. Muitas vezes basta uma única página do seu site para ele concluir “WordPress” e, depois, algumas requisições para montar a lista dos seus plugins e das versões deles. Este artigo detalha os sinais exatos que o Wappalyzer e o WPScan usam, o que você pode remover de forma limpa e o que continuará visível, faça o que fizer.
Definição rápida: Fingerprinting. Solução pronta para usar: Faça o WordPress se passar por outro CMS com o WP Masquerade.
Por que a identificação vem antes do ataque
Os ataques automatizados ao WordPress raramente miram o “seu” site. Eles miram uma versão específica de plugin, conhecida por ser vulnerável, em milhares de sites ao mesmo tempo. Para separar esses sites, um robô responde a três perguntas, nesta ordem: é WordPress? Qual a versão do núcleo? Quais plugins, e em que versão?
O WPScan ilustra bem essa lógica. Por padrão, quando procura plugins em modo agressivo, ele não testa todos os plugins existentes: tenta a lista dos plugins conhecidos por ter uma vulnerabilidade na sua base. Um site que não responde nada de útil a essas perguntas sai mais rápido da fila; um site que anuncia tudo vai parar no grupo certo.
Os sinais passivos: o que a página inicial revela
Uma ferramenta “passiva” não faz nenhuma requisição especial: ela lê o HTML, os cabeçalhos e o JavaScript da página que qualquer visitante recebe. É o caso da extensão de navegador Wappalyzer.
A tag generator
O núcleo adiciona por padrão a função wp_generator ao gancho wp_head. Ela exibe <meta name="generator" content="WordPress 6.9" /> com o número exato da versão. A mesma informação aparece nos feeds: <generator> no RSS 2, atributo version no Atom. Remover a tag do <head> sem tratar os feeds deixa, portanto, a versão acessível em /feed/.
Os caminhos /wp-content/ e /wp-includes/
Folhas de estilo, scripts, imagens: quase todos os recursos de um site WordPress passam por /wp-content/ (temas, plugins, mídia) ou /wp-includes/ (bibliotecas do núcleo). É o sinal mais robusto e, de quebra, entrega o nome dos plugins: /wp-content/plugins/nome-do-plugin/ aparece às claras no código-fonte.
O parâmetro ver=
Os scripts e estilos do núcleo são registrados com uma versão padrão igual à versão do WordPress (default_version = get_bloginfo( 'version' ) em script-loader.php). Nem todos a usam (o jQuery tem o seu próprio número), mas um script registrado sem versão, como wp-includes/js/comment-reply.min.js, é servido com ?ver= seguido da versão do núcleo, mesmo quando a tag generator já sumiu. Os plugins, por sua vez, costumam passar o próprio número de versão nesse mesmo parâmetro.
Os cabeçalhos HTTP
Link: <https://exemplo.com.br/wp-json/>; rel="https://api.w.org/": enviado porrest_output_link_header()nas páginas públicas para anunciar a API REST. O Wappalyzer o reconhece diretamente.X-Pingback: desde o WordPress 4.4, só é enviado em um conteúdo individual (post, página) que aceita pings, e aponta paraxmlrpc.php.- Links curtos:
wp_shortlink_header()adiciona umLinkdo tiposhortlinknos conteúdos.
JavaScript e classes CSS
O editor de blocos deixa classes wp-block-... no conteúdo publicado. No JavaScript, objetos como wp.ajax, uma variável wp_username ou o script wp-embed.min.js bastam para o Wappalyzer. O WooCommerce acrescenta seus próprios marcadores (woocommerce_params, wc_add_to_cart_params).

| Sinal | Onde ver | Revela a versão? | Lido por |
|---|---|---|---|
| Tag generator | <head> de cada página | Sim, exata | Wappalyzer, WPScan |
| Generator dos feeds | /feed/, /feed/atom/ | Sim, exata | WPScan |
| Caminhos wp-content, wp-includes | Código-fonte | Não (mas revela nomes de plugins) | Wappalyzer, WPScan |
Parâmetro ver= | Endereços dos scripts e estilos | Muitas vezes | WPScan |
| Cabeçalho Link api.w.org | Resposta HTTP | Não | Wappalyzer |
| X-Pingback | Resposta HTTP (posts) | Não | Wappalyzer |
| Variáveis JavaScript | Scripts da página | Não | Wappalyzer |
readme.txt de plugin | Requisição dedicada | Sim (Stable tag) | WPScan |
| Impressões MD5 | Requisições a arquivos estáticos | Sim | WPScan |
Como o Wappalyzer decide
O Wappalyzer compara a página com uma base de definições: para cada tecnologia, uma lista de expressões regulares a procurar no HTML, nas meta tags, nos cabeçalhos, nos cookies, nos endereços de scripts e nas variáveis JavaScript. O repositório original se tornou privado em agosto de 2023; a base continua evoluindo em projetos abertos como o webappanalyzer (Enthec), que mantém o mesmo formato.
A definição “WordPress” dessa base é curta e instrutiva:
meta generator:^WordPress(?: ([\d.]+))?, capturando o número da versão;headers:X-Pingbackterminando em/xmlrpc.php, elinkcontendorel="https://api.w.org/";scriptSrcehtml: caminhos/wp-content/ou/wp-includes/,wp-embed.min.js;js:wp.ajax,wp.receiveEmbedMessage,wp_username;implies: PHP e MySQL. Já a definição do WooCommerce exige WordPress (requires).
Consequência prática: um único sinal basta. Remover a tag generator não muda o veredito enquanto os caminhos /wp-content/ continuarem na página. Ao contrário, um site que expõe os marcadores de outro software será classificado nessa outra categoria pelo mesmo mecanismo.
Como o WPScan vai além
O WPScan é um scanner de segurança dedicado ao WordPress, usado tanto por auditores quanto por atacantes. O código-fonte dele é público, o que permite saber exatamente o que ele procura:
- Detecção do WordPress: a página inicial e uma página 404 são examinadas (caminhos, generator, comentários HTML que mencionam WordPress,
admin-ajax.phpem um script embutido). Em modo misto ou agressivo, ele também carregawp-login.phpewp-admin/install.php. - Versão do núcleo: generators dos feeds RSS, Atom e RDF,
readme.html(baixa confiança para versões recentes) e, depois, impressões digitais: ele compara o MD5 de arquivos estáticos com uma base de somas conhecidas, com confiança de 100%. - Plugins: endereços vistos na página inicial e na página 404, padrões nos cabeçalhos, comentários e variáveis JavaScript e, depois, requisições para
/wp-content/plugins/slug/. Uma resposta 200, 401, 403 ou 500 vale como presença. - Versão dos plugins: leitura do
readme.txt, campoStable tag(confiança 80) ou seção do registro de alterações (confiança 50).

As etapas ativas deixam rastros: dezenas de requisições para /wp-content/plugins/.../readme.txt com 404 em poucos segundos denunciam uma enumeração. É também aí que uma defesa pode agir, não respondendo 200 ou 403 para arquivos que não precisam ser públicos.
O que você pode reduzir, e o que continuará visível
O WordPress permite remover vários anúncios com ganchos simples, por exemplo em um plugin próprio:
remove_action( 'wp_head', 'wp_generator' );
add_filter( 'the_generator', '__return_empty_string' ); // feeds incluídos
remove_action( 'wp_head', 'rsd_link' );
remove_action( 'wp_head', 'wp_shortlink_wp_head', 10 );
remove_action( 'template_redirect', 'wp_shortlink_header', 11 );
remove_action( 'wp_head', 'rest_output_link_wp_head', 10 );
remove_action( 'template_redirect', 'rest_output_link_header', 11 );
Atenção à prioridade: remove_action() só funciona se usar a mesma prioridade do momento em que a ação foi adicionada (11 para os dois cabeçalhos). Por outro lado, não adianta procurar wlwmanifest_link: esse link do Windows Live Writer não é mais emitido pelo núcleo desde o WordPress 6.3.
| Sinal | Defesa | Efeito | Limite |
|---|---|---|---|
| Generator | Filtro the_generator | Versão removida das páginas e feeds | Temas e plugins que escrevem o próprio generator |
| Link api.w.org | Remoção dos dois ganchos REST | Anúncio da API eliminado | A API continua acessível em /wp-json/ |
ver= | Reescrita ou remoção do parâmetro | Versão do núcleo menos visível | Pode atrapalhar a invalidação do cache do navegador |
| Caminhos wp-content | Aliases de endereços + regras de servidor | Sem /wp-content/ no HTML | Delicado: CSS, JS e JSON também contêm caminhos |
readme.txt de plugins | Bloqueio no servidor (404) | Versão do plugin mais difícil de ler | Impressões de arquivos estáticos continuam possíveis |
| Impressões MD5 | Nenhuma defesa simples | Só a atualização elimina a vulnerabilidade |
Tenha a hierarquia em mente: esconder a versão não corrige nenhuma falha. Um robô que não consegue identificar o seu site ainda pode tentar o exploit às cegas, e alguns fazem isso. O mascaramento reduz o ruído e tira o seu site das listas de alvos selecionados; atualizações, backups e uma autenticação sólida continuam sendo a base.
Esconder o WordPress ou imitar outro software?
Remover os sinais deixa um site “sem identidade”, o que já é um indício. A outra abordagem consiste em apresentar os marcadores de outro software. É o princípio da imitação de CMS do WP Masquerade, plugin de segurança para WordPress:
| Função | Gratuito | Pro |
|---|---|---|
| Generator do WordPress removido das páginas e dos feeds | Sim | Sim |
| Tag generator autêntica de outro software | 5 perfis (Joomla!, Drupal, PrestaShop, TYPO3, MediaWiki) | 41 perfis |
| Marcadores reconhecidos pelo Wappalyzer (cabeçalhos, variáveis JavaScript) | Não | Sim |
| Links RSD, Windows Live Writer e links curtos removidos | Sim | Sim |
| Anúncios da API REST e do oEmbed removidos | Não | Sim |
| Aliases para wp-content, mídia, wp-includes, plugins, temas | Não | Sim |
| Arquivos readme e traduções do plugin em 404 (Apache, LiteSpeed) | Sim | Sim |
Os limites estão documentados: os nomes das pastas de plugins e temas continuam presentes sob a pasta-raiz deles, os arquivos CSS e JavaScript não são reescritos globalmente, e nenhum resultado é garantido em um detector. Veja também os links técnicos e os endereços dos arquivos.
Teste o seu próprio site em dez minutos
- Abra uma janela anônima (desconectado) e exiba o código-fonte: procure
generator,wp-content,wp-includes,ver=. - Abra
/feed/e procure a tag<generator>. - Leia os cabeçalhos com
curl -sI https://seu-site.com.br/: há umLinkparaapi.w.org? - Rode a extensão Wappalyzer na página inicial e depois em um post.
- Teste
/wp-content/plugins/algum-plugin/readme.txt: um 200 entrega a versão a qualquer pessoa. - Depois de cada ajuste, limpe o cache de páginas: uma cópia antiga pode manter os sinais antigos.
- Se for rodar o WPScan, faça isso somente em um site pelo qual você é responsável.
Para lembrar
- Um único sinal basta para o Wappalyzer: remover a tag generator não adianta enquanto /wp-content/ continuar visível.
- A versão do núcleo também vaza pelos feeds, pelo parâmetro ver= e pelas impressões digitais de arquivos.
- O WPScan lê o Stable tag dos readme.txt de plugins: bloqueie esses arquivos se eles responderem 200.
- remove_action() exige a mesma prioridade da adição (11 para os cabeçalhos Link).
- Esconder reduz o direcionamento automático, mas só as atualizações eliminam uma falha.
Fontes
- webappanalyzer: definições de tecnologias (w.json, entrada WordPress) (abre em uma nova aba)
- webappanalyzer: README (continuação do Wappalyzer, privado desde agosto de 2023) (abre em uma nova aba)
- WordPress Developer: get_the_generator() (abre em uma nova aba)
- WordPress Developer: rest_output_link_header() (abre em uma nova aba)
Outras fontes consultadas: documentação oficial e páginas oficiais dos fornecedores.


