Wirus na stronie WordPress – jak go usunąć krok po kroku
- Typowe objawy
- Przekierowania, spam w Google, czerwone ostrzeżenie w przeglądarce, blokada od hostingu
- Najczęstsza przyczyna
- Nieaktualna wtyczka lub motyw, przejęte hasło, piracki dodatek
- Czas naprawy
- Od kilku godzin do 1–2 dni roboczych
- Czy zrobisz to sam?
- Tak, jeśli swobodnie używasz FTP i phpMyAdmin. Inaczej ryzyko powrotu infekcji jest wysokie
Szybka odpowiedź
Aby usunąć wirusa z WordPressa: zrób kopię całej strony, zmień wszystkie hasła, podmień pliki rdzenia oraz wtyczek i motywów na świeże z oficjalnych źródeł, przeszukaj katalog wp-content/uploads i bazę danych pod kątem obcego kodu, usuń nieznanych administratorów, a na koniec zaktualizuj wszystko i zgłoś stronę do ponownej weryfikacji w Google Search Console. Samo uruchomienie wtyczki skanującej zwykle nie wystarcza.
Wirus na stronie internetowej to potoczna nazwa złośliwego kodu (malware), który ktoś dopisał do plików albo bazy danych Twojego WordPressa. Ten kod robi rzeczy, o których nie wiesz: przekierowuje odwiedzających na strony z kasynami, generuje setki podstron ze spamem, wysyła maile z Twojego serwera albo zostawia tylną furtkę, przez którą atakujący wraca, kiedy chce.
Poniżej opisuję procedurę, którą stosuję przy czyszczeniu zainfekowanych stron. Jest długa, bo krótkie instrukcje typu „zainstaluj wtyczkę i kliknij skanuj” są głównym powodem, dla którego wirusy wracają po tygodniu.
Po czym poznać, że strona ma wirusa
Infekcja rzadko ogłasza się sama. Częściej zauważasz skutki uboczne. Najczęstsze sygnały:
- Przekierowania na obce strony, często tylko na telefonie albo tylko przy wejściu z Google. Ty, zalogowany administrator, możesz ich w ogóle nie widzieć.
- Dziwne wyniki w Google po wpisaniu
site:twojadomena.pl: japońskie znaki, oferty leków, podróbek albo hazardu. - Czerwony ekran ostrzeżenia w Chrome lub Firefoksie przy wejściu na stronę.
- Mail od hostingu o wykryciu złośliwych plików, wysyłce spamu albo zablokowaniu konta.
- Nowi użytkownicy z rolą administratora, których nie zakładałeś.
- Pliki PHP w katalogu z obrazkami albo pliki o losowych nazwach w głównym katalogu.
- Nagły spadek ruchu w Google Analytics lub ostrzeżenie w raporcie „Problemy dotyczące bezpieczeństwa” w Search Console.
Pełną listę objawów z opisem, jak każdy z nich sprawdzić, znajdziesz w artykule Jak sprawdzić, czy strona została zhakowana.
Zanim zaczniesz: trzy rzeczy, których nie rób
- Nie kasuj podejrzanych plików przed zrobieniem kopii. Bez kopii nie odtworzysz strony, jeśli usuniesz coś potrzebnego, i nie ustalisz, którędy weszli atakujący.
- Nie przywracaj od razu starej kopii zapasowej. Infekcja zwykle zaczyna się wcześniej niż objawy. Stara kopia często zawiera tę samą tylną furtkę i zawsze zawiera tę samą lukę.
- Nie zmieniaj haseł z komputera, na którym możesz mieć wirusa. Jeśli hasło do FTP wyciekło przez złośliwe oprogramowanie na Twoim komputerze, nowe hasło wycieknie tą samą drogą.
Usuwanie wirusa z WordPressa krok po kroku
-
Zrób pełną kopię strony w obecnym stanie
Pobierz wszystkie pliki (przez FTP, menedżer plików hostingu albo SSH) i wyeksportuj bazę danych w phpMyAdmin. Opisz kopię wprost, np.
zainfekowana-2026-10-12.zip, żeby nigdy jej przypadkiem nie przywrócić. Przy okazji pobierz z panelu hostingu logi dostępu (access log) z ostatnich tygodni: pokażą, do jakich plików ktoś wysyłał zapytania.# przez SSH, z katalogu nad katalogiem strony tar -czf zainfekowana-$(date +%F).tar.gz public_html/ wp db export zainfekowana-$(date +%F).sql --path=public_html -
Zmień wszystkie hasła, z czystego komputera
Zmień hasło do panelu hostingu, kont FTP i SFTP, użytkownika bazy danych (po zmianie wpisz je w
wp-config.phpwDB_PASSWORD) i wszystkich kont administratorów WordPressa. Wygeneruj też nowe klucze bezpieczeństwa (tzw. salt), co wyloguje wszystkie aktywne sesje, również atakującego:wp config shuffle-saltsBez dostępu do WP-CLI pobierz nowe klucze z
https://api.wordpress.org/secret-key/1.1/salt/i podmień osiem liniidefine('AUTH_KEY'…)wwp-config.php. -
Sprawdź listę administratorów
Wejdź w Użytkownicy i przefiltruj po roli Administrator. Każde konto, którego nie rozpoznajesz, usuń, przypisując jego treści do siebie. Atakujący często zakłada konta o nazwach podobnych do Twoich albo udających wsparcie techniczne.
wp user list --role=administrator --fields=ID,user_login,user_email,user_registeredJeśli panel nie działa, sprawdź tabelę
wp_usersiwp_usermetaw phpMyAdmin (uprawnienia są w kluczuwp_capabilities; prefiks tabel może być inny niżwp_). -
Porównaj pliki rdzenia z oryginałem
WordPress publikuje sumy kontrolne każdego pliku. WP-CLI sprawdzi, które pliki rdzenia zostały zmienione i które są zbędne:
wp core verify-checksums wp plugin verify-checksums --allDrugie polecenie działa tylko dla wtyczek z katalogu wordpress.org. Wtyczek płatnych nie sprawdzi, więc je i tak podmienisz w kroku 7.
-
Poszukaj obcych plików i podejrzanego kodu
Trzy wyszukiwania dają najwięcej trafień. Pliki PHP w katalogu na obrazki (tam nie powinno ich być wcale), pliki zmienione w ostatnich dniach i typowe funkcje używane do ukrywania kodu:
# pliki PHP w uploads – prawie zawsze złośliwe find wp-content/uploads -type f -name "*.php" # pliki PHP zmienione w ciągu ostatnich 14 dni find . -type f -name "*.php" -mtime -14 -printf "%TY-%Tm-%Td %p\n" | sort # typowe wzorce zaciemnionego kodu grep -rlE 'eval\(|base64_decode\(|gzinflate\(|str_rot13\(|assert\(\$_' --include=*.php .Ostatnie polecenie zwróci też niewinne pliki, bo legalne wtyczki również używają
base64_decode. Liczy się kontekst: długi ciąg losowych znaków przekazany doevalna początku pliku to niemal pewna infekcja. Sprawdź też katalogwp-content/mu-plugins(wtyczki ładowane zawsze, niewidoczne na zwykłej liście), plik.htaccessw każdym katalogu,index.phpiwp-config.php. -
Przeszukaj bazę danych
Wiele infekcji nie siedzi w plikach, tylko we wpisach i ustawieniach. W phpMyAdmin uruchom zapytania (zamień prefiks
wp_na swój):SELECT ID, post_title FROM wp_posts WHERE post_content LIKE '%<script%' OR post_content LIKE '%eval(%'; SELECT option_name FROM wp_options WHERE option_value LIKE '%<script%' OR option_value LIKE '%base64_decode%'; SELECT option_value FROM wp_options WHERE option_name IN ('siteurl','home');Wartości
siteurlihomemuszą wskazywać Twoją domenę. Skrypty w treściach sprawdzaj ręcznie: część z nich to Twoje legalne kody, np. Google Tag Managera albo czatu. -
Podmień rdzeń, wtyczki i motywy na świeże kopie
Czyszczenie pojedynczych plików zostawia zbyt dużo miejsc na pomyłkę. Bezpieczniej jest wymienić całość:
- Rdzeń:
wp core download --force --skip-contentnadpiszewp-adminiwp-includesczystą wersją. Potem usuń z głównego katalogu pliki, których nie ma w paczce WordPressa. - Wtyczki i motywy: usuń katalogi i zainstaluj ponownie z wordpress.org albo z konta u twórcy. Usuń wszystko, czego nie używasz, także nieaktywne motywy.
wp-content/uploads: zostaw tylko pliki multimedialne. Usuń każdy plik PHP, JS lub plik bez rozszerzenia, którego nie potrafisz wyjaśnić.
- Rdzeń:
-
Załataj lukę, przez którą weszli atakujący
Zaktualizuj WordPressa, wszystkie wtyczki i motywy, a wersję PHP ustaw na wspieraną (WordPress zaleca obecnie PHP 8.3 lub nowsze). Porzucone wtyczki, czyli bez aktualizacji od ponad roku, zastąp innymi. Pirackie motywy i wtyczki usuń bezwarunkowo. Dodaj do
wp-config.phplinię, która wyłącza edycję plików z panelu:define('DISALLOW_FILE_EDIT', true); -
Zgłoś stronę do Google i obserwuj
Jeśli Google oznaczył stronę jako niebezpieczną, w Search Console otwórz raport „Problemy dotyczące bezpieczeństwa” i wybierz „Poproś o sprawdzenie”, opisując, co zrobiłeś. Według Google rozpatrzenie trwa około doby dla phishingu, kilka dni dla złośliwego oprogramowania i nawet kilka tygodni dla spamu po włamaniu. Szczegóły w artykule Strona przed Tobą zawiera szkodliwe programy. Przez kolejne dwa tygodnie codziennie sprawdzaj, czy nie pojawiły się nowe pliki lub konta.
Gdzie najczęściej ukrywa się złośliwy kod
Atakujący zostawiają kod tam, gdzie właściciel strony nie zagląda. Ta mapa pokazuje miejsca, które sprawdzam przy każdym czyszczeniu.
wp_ może być u Ciebie inny.
<script albo eval(. Trzy mają wstrzyknięty skrypt, jedna zakodowany kod, a „Kontakt” to legalny kod czatu, czyli fałszywy alarm. Dlatego każdą treść trzeba obejrzeć. Zrzut z testowej bazy z symulowaną infekcją.Właściciel sklepu dostaje od klientów sygnał, że strona „otwiera reklamy” na telefonie. Na komputerze wszystko wygląda dobrze. Przyczyną okazuje się kilka linii w .htaccess, które przekierowują tylko przeglądarki mobilne wchodzące z wyszukiwarki, oraz plik PHP w wp-content/uploads/2024/03/, który odtwarza te linie po każdym usunięciu. Samo poprawienie .htaccess pomaga na godzinę. Pomaga dopiero usunięcie pliku-odtwarzacza i aktualizacja wtyczki formularzy, przez którą został wgrany.
Dlaczego wirus wraca po wyczyszczeniu
Jeśli po kilku dniach infekcja wraca, prawie zawsze winna jest jedna z trzech rzeczy:
- Została tylna furtka. Wystarczy jeden mały plik, który przyjmuje polecenia z zewnątrz, żeby atakujący odtworzył wszystko jednym zapytaniem.
- Luka nadal jest otwarta. Jeśli winna była nieaktualna wtyczka, a Ty jej nie zaktualizowałeś, automaty zainfekują stronę ponownie, często w ciągu doby.
- Infekcja przyszła z sąsiedniej strony. Na jednym koncie hostingowym kilka stron zwykle dzieli tego samego użytkownika systemowego. Zainfekowana, zapomniana strona w podkatalogu potrafi zarażać główną. Czyść wszystkie strony na koncie naraz.
Jeśli zainfekowany jest sklep WooCommerce
W sklepie stawka jest wyższa, bo poza reputacją w Google chodzi o dane klientów i pieniądze. Najgroźniejszy rodzaj infekcji to tzw. skimmer: skrypt dopisany do strony zamówienia, który kopiuje dane wpisywane w formularzu i wysyła je na obcy serwer. Sklep działa normalnie, zamówienia spływają, a właściciel dowiaduje się o problemie od klientów lub operatora płatności.
- Sprawdź stronę zamówienia osobno. Otwórz kasę w oknie prywatnym, włącz narzędzia deweloperskie przeglądarki (F12, zakładka Sieć) i przejdź przez formularz bez płacenia. Każde zapytanie do domeny, której nie rozpoznajesz, to sygnał alarmowy.
- Przejrzyj szablony nadpisane w motywie. Katalog
wp-content/themes/twoj-motyw/woocommerce/zawiera własne wersje stron sklepu. Kod skimmera bywa dopisany właśnie do nich albo do ustawień wtyczek pozwalających wstawiać skrypty. - Sprawdź konta i klucze. W ustawieniach WooCommerce, w sekcji kluczy REST API, usuń klucze, których nie tworzyłeś. Zmień klucze integracji z operatorem płatności.
- Pomyśl o obowiązkach wobec klientów. Jeśli doszło do wycieku danych osobowych, RODO (art. 33) wymaga zgłoszenia naruszenia do Prezesa UODO w ciągu 72 godzin od jego stwierdzenia, chyba że jest mało prawdopodobne, by powodowało ryzyko dla osób, których dane dotyczą. Czy zgłoszenie jest potrzebne w Twoim przypadku, oceń z prawnikiem lub inspektorem ochrony danych.
Na czas czyszczenia lepiej włączyć tryb konserwacji z kodem odpowiedzi 503 niż usuwać stronę z serwera. Krótka przerwa z poprawnym kodem nie szkodzi pozycjom w Google, a odwiedzający nie trafiają na zainfekowaną stronę.
Jak zabezpieczyć stronę po czyszczeniu
| Zabezpieczenie | Co daje | Trudność |
|---|---|---|
| Automatyczne aktualizacje wtyczek | Zamyka znane luki zanim użyją ich boty | Łatwe |
| Logowanie dwuskładnikowe dla adminów | Wykradzione hasło przestaje wystarczać | Łatwe |
| Codzienna kopia poza serwerem | Możliwość cofnięcia się bez straty danych | Łatwe |
| Zapora aplikacyjna (WAF) | Blokuje typowe ataki przed WordPressem | Średnie |
| Blokada wykonywania PHP w uploads | Wgrany plik PHP nie uruchomi się | Średnie |
| Monitoring zmian plików | Alarm, gdy pojawi się nowy plik PHP | Średnie |
Blokadę wykonywania PHP w katalogu uploads na serwerze Apache robisz, tworząc w nim plik .htaccess:
<FilesMatch "\.(php|phtml|phar)$">
Require all denied
</FilesMatch>
Na serwerze Nginx tę samą regułę dodaje się w konfiguracji serwera, więc poproś o nią hosting.
Kiedy nie robić tego samemu
Samodzielne czyszczenie ma sens, jeśli strona jest prosta, masz świeżą, sprawdzoną kopię i swobodnie poruszasz się po FTP i phpMyAdmin. Oddaj to specjaliście, gdy:
- strona to sklep z zamówieniami i danymi klientów, a każda godzina przestoju to stracona sprzedaż,
- hosting zablokował konto i daje Ci krótki termin na usunięcie infekcji (zobacz co zrobić, gdy hosting zablokował stronę),
- wirus wrócił po Twoim czyszczeniu,
- infekcja dotyczy kilku stron na jednym koncie.
Ile to kosztuje, opisuję w artykule Ile kosztuje usunięcie wirusa ze strony.
Wolisz, żebym zrobił to za Ciebie?
Czyszczę zainfekowane strony WordPress, zamykam lukę i zgłaszam stronę do weryfikacji w Google. Po czyszczeniu daję 30 dni gwarancji czystości.
Najczęstsze pytania
Czy wtyczka bezpieczeństwa sama usunie wirusa z WordPressa?
Czasem tak, ale zwykle tylko częściowo. Skanery dobrze znajdują znane sygnatury w plikach, gorzej radzą sobie z kodem w bazie danych, plikami w nietypowych miejscach i tylnymi furtkami napisanymi pod konkretny atak. Skan wtyczką to dobry start, a nie dowód, że strona jest czysta.
Czy wystarczy przywrócić kopię zapasową sprzed infekcji?
Rzadko. Infekcja często zaczyna się tygodnie przed pierwszymi objawami, więc kopia może już zawierać tylną furtkę. Nawet czysta kopia ma tę samą lukę, przez którą weszli atakujący. Po przywróceniu trzeba zaktualizować wszystko, zmienić hasła i sprawdzić pliki.
Ile trwa usunięcie wirusa ze strony WordPress?
Typowa infekcja małej strony firmowej to kilka godzin pracy. Rozbudowany sklep, wiele zainfekowanych stron na jednym hostingu albo infekcja w bazie danych może wydłużyć to do dnia lub dwóch. Zdjęcie ostrzeżenia Google po zgłoszeniu do weryfikacji zajmuje zwykle kilka dni.
Skąd się bierze wirus na stronie WordPress?
Najczęściej z nieaktualnej wtyczki lub motywu ze znaną luką, z wykradzionego lub słabego hasła (do panelu, FTP albo hostingu) oraz z pirackich, tzw. nulled, motywów i wtyczek, które bywają zainfekowane już w paczce instalacyjnej.