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.php de 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_generator atua tanto na tag generator do HTML quanto no generator dos feeds. O remove_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.txt ou pelo ver= 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 com expose_php = Off no php.ini
  • O readme.html volta 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:

Dúvidas sobre WordPress? Quem publica este site fica no Japão e responde em japonês. Contato (em japonês)

お気軽にご相談ください

お見積りへ お問い合わせへ
▲