2026年11月12日

2026年11月12日

Jak ukryć wersję WordPress: generator, ver= i readme.html

Ten artykuł jest zlokalizowaną wersją japońskiego oryginału. Przeczytaj japoński oryginał

W stanie początkowym WordPress zapisuje swój numer wersji w HTML stron i w kanałach. Atakujący mogą na jego podstawie sprawdzać, czy dana wersja ma znane luki. W tym artykule pokazuję, gdzie wersja jest widoczna i jak ją ukryć. Treść odpowiada stanowi na październik 2026.

Na początku warto wiedzieć jedno: ukrywanie wersji to tylko środek pomocniczy. Wersję można też zgadnąć choćby z zawartości plików CSS i JavaScript, więc ukrycie nie zawsze uniemożliwia jej ustalenie. Najlepiej działa utrzymywanie rdzenia WordPress, wtyczek i motywów w najnowszych wersjach.

Gdzie wyświetla się wersja

Miejsce Co jest wyświetlane Rozwiązanie
<head> w HTML Tag w rodzaju <meta name="generator" content="WordPress 6.9.4"> Filtr the_generator
Kanały RSS i Atom Wiersz w rodzaju <generator>https://wordpress.org/?v=6.9.4</generator> Również filtr the_generator
Adresy URL CSS i JavaScript ?ver= w rodzaju style.min.css?ver=6.9.4 Filtry style_loader_src i script_loader_src
Nagłówki HTTP X-Powered-By: PHP/8.3.x (to wersja PHP, nie WordPress) expose_php w php.ini
readme.html Informacja, że używasz WordPress (obecny readme.html nie zawiera numeru wersji) Zablokuj dostęp

Informacje o witrynie zwracane przez /wp-json/ w REST API (nazwa, opis, URL, strefa czasowa, przestrzenie nazw itp.) nie zawierają wersji WordPress. Aby ukryć wersję, nie trzeba przycinać danych wyjściowych REST API.

Krok 1: sprawdź, co jest teraz wyświetlane

Zamień adres na adres własnej witryny i wykonaj polecenia na swoim komputerze lub serwerze. Jeśli korzystasz z wtyczek cache lub CDN, po zmianie wyczyść cache, a dopiero potem sprawdzaj.

# Tag generator w HTML
curl -s https://example.com/ | grep -i 'name="generator"'

# Generator w kanale
curl -s https://example.com/feed/ | grep -i '<generator>'

# Lista wartości ver= dopisanych do CSS i JS
curl -s https://example.com/ | grep -oE 'ver=[0-9][0-9.]*' | sort | uniq -c

# Nagłówek HTTP X-Powered-By
curl -sI https://example.com/ | grep -i 'x-powered-by'

# Czy readme.html da się otworzyć (200 oznacza, że tak)
curl -s -o /dev/null -w '%{http_code}\n' https://example.com/readme.html

Jeśli na liście ver= jest wartość taka sama jak wersja WordPress wyświetlana w panelu w „Kokpit" → „Aktualizacje" (Dashboard → Updates), to z tych plików CSS lub JS można poznać wersję WordPress. Gdy rdzeń WordPress lub motyw ładuje CSS i JS bez podania wersji, do ver= trafia wersja WordPress.

Krok 2: wybierz, gdzie umieścić kod

Kod z tego artykułu umieść w jednym z dwóch miejsc.

  • mu-plugin (zalecane): jeśli umieścisz plik PHP w katalogu wp-content/mu-plugins/ (utwórz go, jeśli nie istnieje), zostanie wczytany bez włączania. Efekt zostaje po zmianie motywu
  • functions.php motywu potomnego: jeśli wpiszesz to w functions.php motywu nadrzędnego, zniknie przy aktualizacji motywu

Jeśli wybierasz mu-plugin, zapisz kod z następnego kroku w jednym pliku o nazwie w rodzaju wp-content/mu-plugins/hide-wp-version.php.

Krok 3: ukryj wersję w tagu generator i w ver=

<?php
/**
 * Plugin Name: Hide WordPress Version
 * Description: Ukrywa wersję WordPress widoczną w tagu generator i w ver= w CSS i JS.
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

// Opróżnia <meta name="generator"> w HTML i <generator> w kanale.
add_filter( 'the_generator', '__return_empty_string' );

/**
 * Tylko gdy ver= w CSS i JS jest taki sam jak wersja WordPress, zastępuje go inną wartością.
 * Nie usuwa ver=, tylko go zastępuje, więc cache przeglądarki odświeża się po aktualizacji 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 );

Najważniejsze punkty:

  • Filtr the_generator działa zarówno na tag generator w HTML, jak i na generator w kanale. remove_action( 'wp_head', 'wp_generator' ); usuwa tylko tag w HTML, więc nie działa na kanał
  • Jeśli usuniesz wszystkie ?ver=, po aktualizacji wtyczek lub motywów przeglądarka może dalej używać starych CSS i JS. Powyższy kod zastępuje wartość innym ciągiem utworzonym z wersji tylko wtedy, gdy jest równa wersji WordPress. Po aktualizacji WordPress wartość też się zmienia, więc cache się odświeża
  • Wartości ver= z własnymi numerami wersji nadawanymi przez wtyczki lub motywy nie są zmieniane

Po zapisaniu sprawdź poleceniami z kroku 1, że generator nie jest wyświetlany i że na liście ver= nie została wersja WordPress. Jeśli używasz wtyczek cache, wyczyść cache, zanim sprawdzisz.

Krok 4: wyłącz nagłówek X-Powered-By

X-Powered-By to nagłówek dodawany nie przez WordPress, lecz przez PHP i ujawnia wersję PHP. Aby go wyłączyć, ustaw expose_php na Off w pliku konfiguracyjnym PHP (php.ini). To ustawienie można zmienić tylko w php.ini.

expose_php = Off

To przykład dla Ubuntu na VPS z PHP-FPM (8.3 dopasuj do używanej wersji PHP).

# Sprawdź obecne ustawienie
grep -n '^expose_php' /etc/php/8.3/fpm/php.ini

# Po zmianie uruchom ponownie PHP-FPM
sudo systemctl restart php8.3-fpm

W pakietowym php.ini w Ubuntu domyślnie jest expose_php = Off. Jeśli nagłówek mimo to się pojawia, sprawdź, czy nie jest używany inny php.ini. Na hostingach ustawienie to można czasem zmienić w ustawieniach PHP w panelu, a czasem nie.

Jeśli nie możesz zmienić php.ini, nagłówek da się usunąć też kodem WordPress. Hak send_headers jest jednak uruchamiany przez WordPress przy wyświetlaniu stron frontendu, więc nie działa w panelu administracyjnym ani na ekranie logowania.

add_action( 'send_headers', function () {
	header_remove( 'X-Powered-By' );
} );

Krok 5: zablokuj dostęp do readme.html i license.txt

readme.html i license.txt to pliki rdzenia WordPress. Obecny readme.html nie zawiera numeru wersji, ale ujawnia, że używasz WordPress.

Nawet jeśli je usuniesz, wrócą po aktualizacji rdzenia WordPress. Mniej pracy niż usuwanie wymaga zablokowanie dostępu na serwerze WWW.

Apache (.htaccess)

Dopisz do pliku .htaccess w katalogu WordPress. Fragment między # BEGIN WordPress a # END WordPress jest przepisywany przez WordPress, więc wpisz to poza nim. To składnia Apache 2.4 (Order i Deny from all to stara składnia Apache 2.2).

<FilesMatch "^(readme\.html|license\.txt)$">
    Require all denied
</FilesMatch>

Nginx

Dopisz do bloku server witryny, sprawdź konfigurację i przeładuj.

location ~* ^/(readme\.html|license\.txt)$ {
    deny all;
}
sudo nginx -t && sudo systemctl reload nginx

Po dopisaniu uruchom curl -s -o /dev/null -w '%{http_code}\n' https://example.com/readme.html i sprawdź, czy wraca 403.

Czego ukrycie nie zabezpiecza

  • Zawartość plików CSS i JS WordPress różni się nieznacznie między wersjami, więc po pobraniu plików i porównaniu da się odgadnąć wersję
  • Z readme.txt lub ver= wtyczek i motywów można czasem poznać wersje wtyczek. Atakowane są częściej luki we wtyczkach niż w rdzeniu
  • Osoby, które mogą zalogować się do panelu, nadal widzą wersję jak dotąd

Dlatego razem z ukrywaniem wersji aktualizuj rdzeń, wtyczki i motywy, usuwaj nieużywane wtyczki i wyłącz edycję plików w panelu administracyjnym.

Podsumowanie

  • Wersja pojawia się głównie w generatorze w HTML i w kanałach oraz w ?ver= w CSS i JS. /wp-json/ w REST API nie zawiera wersji WordPress
  • Przez add_filter( 'the_generator', '__return_empty_string' ); usuniesz generator zarówno z HTML, jak i z kanału
  • Nie usuwaj ?ver=, tylko zastępuj wyłącznie wartość równą wersji WordPress — wtedy odświeżanie cache nie zostanie zatrzymane
  • X-Powered-By wyłączysz przez expose_php = Off w php.ini
  • readme.html po usunięciu wraca przy aktualizacji, więc zablokuj do niego dostęp na serwerze WWW
  • Ukrywanie to środek pomocniczy; najważniejsze jest ciągłe aktualizowanie

Powiązane artykuły:

Pytania o WordPress? Wydawca tej witryny ma siedzibę w Japonii i odpowiada po japońsku. Kontakt (po japońsku)

お気軽にご相談ください

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