Otwórz dowolną witrynę WordPress na świecie i dodaj /readme.html do URL. W zdecydowanej większości przypadków zobaczysz czystą stronę HTML, która w nagłówku dumnie ogłasza dokładną wersję WordPress. To samo dotyczy /license.txt, który jest nieco mniej konkretny, ale nadal potwierdza, że witryna działa na WordPress i daje przybliżone pojęcie o tym, jak niedawna jest instalacja.
Oba pliki są dostarczane z core WordPress. Są tworzone ponownie przy każdej aktualizacji. Żaden z nich nie jest potrzebny do funkcjonowania witryny. Jedyna publiczność, którą realistycznie obsługują, to automatyczne skanery, które identyfikują witryny według wersji core, aby mogły dopasować wynik do listy znanych podatności. Ten przewodnik wyjaśnia, dlaczego to ma znaczenie w praktyce i jak czysto zablokować pliki na Apache, nginx i shared hostingu, gdzie masz mniej bezpośredniej kontroli.
Dlaczego ma znaczenie, że readme.html jest osiągalny?
Szczera odpowiedź: sam w sobie niezbyt wiele. Znajomość wersji WordPress witryny nie jest podatnością. Wersja core WordPress nie jest tajemnicą, a zdeterminowany atakujący może to zwykle i tak ustalić, na przykład przez tagi generator meta, parametr wersji na załadowanych skryptach i stylach, lub przez strukturę odpowiedzi REST API.
To, co zmienia sytuację, to sposób, w jaki dziś działa eksploatacja na dużą skalę. Skanery masowe nie wybierają celu, a następnie szukają błędów. Wybierają CVE, budują listę każdej domeny w internecie, która uruchamia dotkniętą wersję, i odpalają exploit na całą listę. Najtańszym sposobem zbudowania tej listy jest równoległe pobieranie readme.html na milionach domen i parsowanie wersji z nagłówka. Cokolwiek czyni witrynę niewidoczną dla tego kroku filtrowania, usuwa Cię z listy kandydatów, zanim faktyczny exploit zostanie wykonany.
Usunięcie readme.html nie czyni witryny bezpieczną. Usuwa jeden z najtańszych odcisków palców, co w praktyce oznacza, że nie pojawiasz się już na automatycznych listach "witryn WordPress uruchamiających wersję X.Y.Z". To kilka minut pracy, choć nie najbardziej krytyczne hartowanie bezpieczeństwa, jakie możesz wykonać.
Co z license.txt i innymi plikami core?
Ten sam typ pliku, nieco mniej interesujący:
license.txtzawiera tekst licencji GPL. Nie zawiera numeru wersji, ale jego istnienie w katalogu głównym WordPress jest silnym sygnałem, że witryna działa na WordPress.wp-config-sample.phpjest dostarczany z każdą instalacją. Nie zawiera danych uwierzytelniających, ale ujawnia, że nikt nie posprzątał po konfiguracji.readme.htmlto ten z problemem ujawniania wersji.
Reguła blokowania poniżej obejmuje wszystkie trzy w jednym ujęciu. Nie ma dobrego powodu, aby pozostawić któryś z nich publicznie osiągalnym.
Opcja 1: Blokowanie przez .htaccess (Apache i LiteSpeed)
Jeśli Twój host działa na Apache lub LiteSpeed (co obejmuje większość shared hostów na rynku niemieckojęzycznym: All Inkl, IONOS, Strato, DomainFactory, Hostinger i większość resellerów), możesz dodać następujący blok do pliku .htaccess w katalogu głównym WordPress:
<FilesMatch "^(readme\.html|license\.txt|wp-config-sample\.php)$">
Require all denied
</FilesMatch>Fragment używa składni Apache 2.4, co każdy host uruchamia od lat. Jeśli nadal utknąłeś na Apache 2.2 (w 2026 niezwykle rzadkie, ale możliwe na przestarzałym hostingu), użyj starszej składni:
<FilesMatch "^(readme\.html|license\.txt|wp-config-sample\.php)$">
Order allow,deny
Deny from all
</FilesMatch>Umieść blok nad znacznikiem # BEGIN WordPress. Wszystko między # BEGIN WordPress i # END WordPress jest zarządzane przez sam WordPress i jest przepisywane, gdy zmieniają się permalinki lub uruchamiane są aktualizacje core. Wszystko poza tymi znacznikami jest pozostawione w spokoju.
Po zapisaniu pliku otwórz https://twojadomena.pl/readme.html w prywatnym oknie przeglądarki. Powinieneś otrzymać 403 Forbidden. To samo dotyczy /license.txt. Jeśli nadal widzisz zawartość pliku, Twój host albo całkowicie ignoruje .htaccess (rzadkie na Apache, normalne na nginx), albo ma AllowOverride ustawione na wartość, która usuwa dyrektywy FilesMatch. Przejdź do Opcji 3.
Opcja 2: Blokowanie przez nginx
Na nginx nie ma .htaccess. Jeśli zarządzasz własnym serwerem (VPS w Hetzner, Netcup, DigitalOcean, lub managed nginx host, gdzie kontrolujesz konfigurację), dodaj następujące wewnątrz bloku server swojej witryny:
location ~* ^/(readme\.html|license\.txt|wp-config-sample\.php)$ {
deny all;
return 403;
}Przeładuj nginx za pomocą sudo nginx -t && sudo systemctl reload nginx, następnie przetestuj za pomocą curl -I https://twojadomena.pl/readme.html. Pierwsza linia odpowiedzi powinna brzmieć HTTP/2 403.
Kilka managed WordPress hostów, którzy używają nginx wewnętrznie (Raidboxes, Kinsta, WP Engine, Cloudways) dostarcza standardowych reguł tego typu. Warto sprawdzić dokumentację hosta. Jeśli tego nie robią, wsparcie zwykle dodaje regułę na żądanie.
Opcja 3: Shared hosting, gdzie nadpisania .htaccess nie działają
Niektóre ściśle zablokowane shared hosty działają na nginx i całkowicie ignorują .htaccess. Inne działają na Apache, ale z restrykcyjnymi regułami AllowOverride. Jeśli ani Opcja 1, ani Opcja 2 nie jest dostępna, masz trzy rozsądne alternatywy, posortowane według trwałości:
- Użyj wtyczki bezpieczeństwa, która zajmuje się hartowaniem plików core. Solid Security i All In One WP Security & Firewall mają oba przełącznik "usuń pliki core" lub "ukryj wersję WordPress", który obsługuje readme.html. Wordfence w trybie Extended Protection może również blokować pliki na poziomie WAF. Zaletą jest, że te ustawienia automatycznie przeżywają aktualizacje WordPress.
- Opróżnij plik przez wtyczkę Must Use. Jeśli reguła na poziomie serwera jest niemożliwa, najbardziej niezawodnym podejściem jest mała mu-plugin, która nadpisuje readme.html i license.txt pustą zawartością po każdej aktualizacji WordPress. Zobacz powiązany artykuł z fragmentem kodu w naszej bazie wiedzy.
- Usuń pliki ręcznie. Najszybsza poprawka zajmuje dziesięć sekund przez SFTP: po prostu usuń
readme.html,license.txtiwp-config-sample.phpz katalogu głównego WordPress. Problem polega na tym, że aktualizacje core WordPress przywracają pliki. Musisz pamiętać, aby je usuwać ponownie po każdej dużej aktualizacji, i dlatego wtyczka lub reguła webserwera jest lepszą długoterminową odpowiedzią.
Czego nie robić
Kilka podejść, które pojawiają się na starszych blogach, ale są gorsze niż się wydają:
- Przemianowywanie plików. Przemianowanie
readme.htmlnareadme.html.oldwygląda schludnie, ale nie pomaga. WordPress po prostu utworzy oryginał ponownie przy następnej aktualizacji, a teraz masz dwa pliki zamiast jednego. - Ustawienie uprawnień pliku na 000. To blokuje odczyt na większości hostów, ale następna aktualizacja core resetuje uprawnienia, a na niektórych hostach łamie nawet samą aktualizację, jeśli WordPress nie może odczytać pliku podczas procesu aktualizacji.
- Edytowanie plików, aby usunąć numer wersji. Kuszące, ale bezcelowe. WordPress przywraca oryginał przy aktualizacji, a nawet edytowany readme.html nadal potwierdza, że witryna działa na WordPress.
Wzorzec jest za każdym razem ten sam: wszystko, co znajduje się wewnątrz katalogu instalacji WordPress i nie jest chronione regułą webserwera, jest resetowane przy aktualizacji. Zablokuj na poziomie webserwera lub użyj wtyczki, która wie, jak aktywnie utrzymywać się podczas aktualizacji.
Jak zweryfikować swoją konfigurację
- Otwórz
https://twojadomena.pl/readme.htmlw prywatnym oknie. Oczekiwany rezultat: strona403 Forbidden(lub404, jeśli wybrałeś usunięcie). - Ta sama kontrola dla
https://twojadomena.pl/license.txtihttps://twojadomena.pl/wp-config-sample.php. - Jeśli nadal widzisz zawartość pliku, opróżnij wszelkie cache stojące przed witryną (Cloudflare, Varnish, cache strony na poziomie serwera, takie jak LiteSpeed Cache lub WP Rocket) i spróbuj ponownie. Buforowane odpowiedzi mogą ukrywać zmianę godzinami.
- Uruchom nowy skan InspectWP. Kontrola wyeksponowanego readme.html w sekcji bezpieczeństwa powinna stać się zielona.
Skoro już tu jesteś
Ten sam rodzaj reguły FilesMatch lub location warto zastosować do kilku innych endpointów, które regularnie pojawiają się w skanach InspectWP: wp-config.php.bak, wp-config.php.swp, .git/, .env, phpinfo.php i każdy info.php, który deweloper zostawił podczas debugowania. Ten sam mechanizm, te same pięć linii konfiguracji, i usuwasz w jednym ujęciu całą klasę przypadkowego fingerprintingu i wyciekania danych uwierzytelniających.