2026年11月12日
2026年11月12日
Como ocultar a versão do WordPress: generator, ver= e readme.html
Este artigo é uma edição localizada do original em japonês. Ler o original em japonês
Por padrão, o WordPress escreve o número da sua versão no HTML das páginas e nos feeds. Um invasor pode usar essa informação para descobrir se a versão tem alguma vulnerabilidade conhecida. Este artigo mostra onde a versão aparece e como ocultá-la. O conteúdo é de outubro de 2026.
A primeira coisa que você precisa saber é que ocultar a versão é apenas uma medida complementar. Há outras formas de deduzir a versão, como o conteúdo dos arquivos CSS e JavaScript, então ocultá-la não garante que ela não seja identificada. O que mais funciona é manter o núcleo do WordPress, os plugins e os temas sempre atualizados.
Onde a versão aparece
| Local | O que aparece | Solução |
|---|---|---|
<head> do HTML |
Uma tag como <meta name="generator" content="WordPress 6.9.4"> |
Filtro the_generator |
| Feeds RSS e Atom | Uma linha como <generator>https://wordpress.org/?v=6.9.4</generator> |
Também o filtro the_generator |
| URLs de CSS e JavaScript | O ?ver=, como em style.min.css?ver=6.9.4 |
Filtros style_loader_src e script_loader_src |
| Cabeçalhos HTTP | X-Powered-By: PHP/8.3.x (é a versão do PHP, não do WordPress) |
expose_php no php.ini |
readme.html |
Revela que o WordPress está em uso (o readme.html atual não traz o número da versão) | Negar o acesso |
As informações do site retornadas pela /wp-json/ da REST API (nome, descrição, URL, fuso horário, namespaces etc.) não incluem a versão do WordPress. Não é preciso reduzir a saída da REST API com o objetivo de ocultar a versão.
Passo 1: confira como a versão aparece hoje
Troque pela URL do seu site e execute no seu computador ou no servidor. Se você usa plugins de cache ou uma CDN, limpe o cache depois de qualquer alteração antes de conferir.
# Tag generator do HTML
curl -s https://example.com/ | grep -i 'name="generator"'
# generator do feed
curl -s https://example.com/feed/ | grep -i '<generator>'
# Lista dos valores de ver= presentes em CSS e JS
curl -s https://example.com/ | grep -oE 'ver=[0-9][0-9.]*' | sort | uniq -c
# Cabeçalho HTTP X-Powered-By
curl -sI https://example.com/ | grep -i 'x-powered-by'
# Se o readme.html pode ser lido (200 significa que pode)
curl -s -o /dev/null -w '%{http_code}\n' https://example.com/readme.html
Se na lista de ver= houver o mesmo valor da versão do WordPress exibida em "Painel" → "Atualizações" (Dashboard → Updates) no painel de administração, esses CSS e JS revelam a versão do WordPress. Quando o núcleo do WordPress ou o tema carrega um CSS ou JS sem especificar a versão, a versão do WordPress vai para o ver=.
Passo 2: decida onde colocar o código
O código deste artigo deve ficar em um destes lugares.
- mu-plugin (recomendado): se você colocar um arquivo PHP na pasta
wp-content/mu-plugins/(crie-a se não existir), ele é carregado sem precisar ativar. O efeito continua mesmo se você trocar de tema functions.phpde um tema filho: se você escrever no functions.php do tema pai, o código se perde quando o tema é atualizado
Se optar pelo mu-plugin, junte o código dos próximos passos em um único arquivo, com um nome como wp-content/mu-plugins/hide-wp-version.php.
Passo 3: oculte a versão na tag generator e no ver=
<?php
/**
* Plugin Name: Hide WordPress Version
* Description: oculta a versão do WordPress na tag generator e no ver= de CSS e JS.
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
// Esvazia o <meta name="generator"> do HTML e o <generator> dos feeds.
add_filter( 'the_generator', '__return_empty_string' );
/**
* Só substitui por outro valor quando o ver= de CSS e JS é igual à versão do WordPress.
* Como o ver= é substituído e não removido, o cache do navegador é renovado depois de atualizar o WordPress.
*/
function wpdr_replace_wp_version_query( $src ) {
if ( ! is_string( $src ) || '' === $src ) {
return $src;
}
$query = wp_parse_url( $src, PHP_URL_QUERY );
if ( empty( $query ) ) {
return $src;
}
parse_str( $query, $args );
$wp_version = get_bloginfo( 'version' );
if ( isset( $args['ver'] ) && $args['ver'] === $wp_version ) {
$src = add_query_arg( 'ver', substr( wp_hash( $wp_version ), 0, 10 ), $src );
}
return $src;
}
add_filter( 'style_loader_src', 'wpdr_replace_wp_version_query', 20 );
add_filter( 'script_loader_src', 'wpdr_replace_wp_version_query', 20 );
Os pontos principais são estes.
- O filtro
the_generatoratua tanto na tag generator do HTML quanto no generator dos feeds. Oremove_action( 'wp_head', 'wp_generator' );remove apenas a tag do HTML e não afeta os feeds - Se você removesse todos os
?ver=, depois de atualizar plugins ou temas o navegador poderia continuar usando o CSS e o JS antigos. O código acima só substitui, por outra string gerada a partir da versão, o valor que for igual à versão do WordPress. Ao atualizar o WordPress, o valor também muda, então o cache é renovado - Os
ver=com número de versão próprio de plugins ou temas não são alterados
Depois de salvar, use os comandos do passo 1 para confirmar que o generator não aparece mais e que a versão do WordPress não permanece na lista de ver=. Se você usa plugins de cache, limpe o cache antes de conferir.
Passo 4: desative o cabeçalho X-Powered-By
O X-Powered-By é um cabeçalho adicionado pelo PHP, não pelo WordPress, e revela a versão do PHP. Para desativá-lo, defina expose_php como Off no arquivo de configuração do PHP (php.ini). Essa configuração só pode ser alterada no php.ini.
expose_php = Off
Este é um exemplo com PHP-FPM no Ubuntu de um VPS (troque o 8.3 pela versão do PHP que você usa).
# Verifica a configuração atual
grep -n '^expose_php' /etc/php/8.3/fpm/php.ini
# Depois de alterar, reinicie o PHP-FPM
sudo systemctl restart php8.3-fpm
O php.ini do pacote do Ubuntu já vem com expose_php = Off por padrão. Se o cabeçalho ainda aparece, verifique se não há outro php.ini sendo usado. Em hospedagens compartilhadas, às vezes dá para alterar isso na configuração de PHP do painel e, às vezes, não.
Se você não consegue mudar o php.ini, também é possível remover o cabeçalho pelo código do WordPress. Mas o send_headers é um hook executado quando o WordPress gera as páginas do front-end, então não afeta o painel nem a tela de login.
add_action( 'send_headers', function () {
header_remove( 'X-Powered-By' );
} );
Passo 5: negue o acesso ao readme.html e ao license.txt
O readme.html e o license.txt são arquivos do núcleo do WordPress. O readme.html atual não traz o número da versão, mas revela que o WordPress está em uso.
Mesmo que você os apague, eles voltam quando o núcleo do WordPress é atualizado. Negar o acesso no servidor web dá menos trabalho do que apagá-los.
No Apache (.htaccess)
Acrescente ao .htaccess que fica na pasta do WordPress. O trecho entre # BEGIN WordPress e # END WordPress é reescrito pelo WordPress, então escreva fora dele. É a sintaxe do Apache 2.4 (Order e Deny from all são a sintaxe antiga do Apache 2.2).
<FilesMatch "^(readme\.html|license\.txt)$">
Require all denied
</FilesMatch>
No Nginx
Acrescente ao bloco server do site e recarregue depois de verificar a configuração.
location ~* ^/(readme\.html|license\.txt)$ {
deny all;
}
sudo nginx -t && sudo systemctl reload nginx
Depois de acrescentar, execute curl -s -o /dev/null -w '%{http_code}\n' https://example.com/readme.html e confirme que retorna 403.
O que ocultar não impede
- O conteúdo dos arquivos CSS e JS do WordPress muda um pouco a cada versão, então é possível deduzir a versão baixando os arquivos e comparando-os
- Às vezes dá para saber a versão dos plugins pelo
readme.txtou pelover=de plugins e temas. O que mais costuma ser alvo são as vulnerabilidades dos plugins, mais do que as do núcleo - Para quem consegue entrar no painel de administração, a versão continua sendo exibida como sempre
Por isso, junto com a ocultação da versão, atualize o núcleo, os plugins e os temas, remova os plugins que não usa e desative a edição de arquivos pelo painel, entre outras medidas.
Resumo
- A versão aparece principalmente no generator do HTML e dos feeds e no
?ver=de CSS e JS. A/wp-json/da REST API não inclui a versão do WordPress - Com
add_filter( 'the_generator', '__return_empty_string' );é possível remover o generator tanto do HTML quanto dos feeds - Em vez de remover o
?ver=, substitua apenas o valor igual à versão do WordPress; assim a atualização do cache não é interrompida - O
X-Powered-Byé desativado comexpose_php = Offno php.ini - O
readme.htmlvolta com as atualizações mesmo se for apagado, então negue o acesso no servidor web - Ocultar é só uma medida complementar; o mais importante é continuar atualizando
Artigos relacionados:
- Como configurar os cabeçalhos de segurança do WordPress: .htaccess, Nginx e functions.php
- Como restringir o acesso à REST API do WordPress
- Como desativar o editor de arquivos de temas e plugins do WordPress: DISALLOW_FILE_EDIT
Dúvidas sobre WordPress? Quem publica este site fica no Japão e responde em japonês. Contato (em japonês)