Strona WordPress zhakowana lub z wirusem — co robić krok po kroku
Strona została zhakowana albo jest zawirusowana: przekierowuje na obce domeny, w Google ma podstrony z lekami albo hosting zablokował konto? Przeprowadzimy Cię od pierwszych 15 minut po pełne czyszczenie, z osobnymi krokami dla właściciela firmy i dla osoby z dostępem do FTP lub SSH.
W skrócie
- Nie kasuj niczego w pośpiechu. Zrób kopię zainfekowanej strony (pliki i baza), zapisz objawy z godziną, pobierz logi z hostingu i przenieś to wszystko poza serwer.
- Z czystego urządzenia zmień hasła do hostingu, FTP i poczty, a nieznanym administratorom w WordPressie odbierz rolę.
- Porównaj pliki z oficjalnymi sumami kontrolnymi (
wp core verify-checksums,wp plugin verify-checksums --all), czytając wszystkie ostrzeżenia, a nie tylko ostatnią linię. Przeszukajuploads,mu-plugins,.htaccess,.user.ini, bazę oraz zadania cron. - Podmień rdzeń, wtyczki i motyw na kopie z oficjalnych źródeł, usuń wersje „nulled”, wyczyść cache, zmień klucze SALT, klucze API i wszystkie hasła jeszcze raz.
- Dopiero po czyszczeniu poproś o sprawdzenie w Google Search Console (Problemy dotyczące bezpieczeństwa).
- Jeśli atakujący mógł dostać się do danych klientów, masz 72 godziny od stwierdzenia naruszenia na ocenę i ewentualne zgłoszenie do UODO.
Włamanie na stronę albo wirus na stronie WordPress rzadko wygląda jak w filmie. Zwykle strona działa, a problem widzą inni: klient pisze, że z telefonu trafił na stronę z kasynem, Google pokazuje podstrony z japońskimi znakami, a hosting przysyła maila o zablokowaniu konta za rozsyłanie spamu. Ty po zalogowaniu widzisz wszystko jak zawsze.
Ten poradnik przeprowadzi Cię przez cały proces: rozpoznanie, ograniczenie szkód, czyszczenie plików i bazy, zdjęcie ostrzeżeń Google i zabezpieczenie strony po incydencie. Polecenia WP-CLI oraz wyszukiwania find i grep sprawdziliśmy na WordPressie 7.1.3 z WP-CLI 2.12. Pozostałe poradniki o włamaniach i ochronie strony znajdziesz w dziale Bezpieczeństwo i wirusy.
Pierwsze 15 minut po wykryciu włamania
Ścieżka: każdy. Tych pięć kroków nie wymaga wiedzy technicznej, a chroni przed najczęstszymi błędami popełnianymi w panice.
- Niczego nie usuwaj w pośpiechu. Skasowanie podejrzanego pliku albo przywrócenie przypadkowej kopii zaciera ślady i zwykle nie usuwa przyczyny. Zrób zrzuty ekranu objawów i zapisz, kiedy je zauważyłeś.
- Zmień hasło do panelu hostingu i do poczty z czystego urządzenia. Konto hostingu daje dostęp do plików, bazy i kopii. Jeśli Twój komputer może być zainfekowany (programy kradnące hasła to częsta droga włamania), użyj telefonu albo innego komputera.
- Odbierz dostęp nieznanym administratorom, ale ich nie kasuj. W kokpicie: Użytkownicy → filtr „Administrator”. Zanotuj nieznane konta (login, e-mail, data rejestracji), zaznacz je i wybierz Zmień rolę na… → „Brak roli w witrynie”. Konto traci dostęp, a ślady zostają. Usuniesz je po zrobieniu kopii.
- Zrób kopię zainfekowanej strony. Pliki i bazę danych, z panelu hostingu albo przez prośbę do hostingu. Nazwij ją wyraźnie, np.
ZAINFEKOWANA-2026-10-12, i trzymaj poza serwerem. - Napisz do hostingu. Zapytaj, czy widzą infekcję, czy dotyczy innych stron na koncie, czy mają logi dostępu z ostatnich tygodni i kopie sprzed ataku.
Objawy włamania na stronę WordPress
Ścieżka: każdy. Infekcja zwykle ma zarabiać: na ruchu na Twojej stronie, na Twojej domenie albo na mocy Twojego serwera. Od celu zależy, co widać. Tabela zbiera objawy, które spotykamy najczęściej, i miejsca, w których szukamy przyczyny.
| Co widzisz | Co to zwykle oznacza | Gdzie szukać |
|---|---|---|
| Przekierowanie na obcą stronę tylko z telefonu albo tylko po wejściu z Google | Przekierowanie warunkowe: kod sprawdza urządzenie, źródło wejścia i to, czy jesteś zalogowany | .htaccess, wstrzyknięty JavaScript w wp_options i wp_posts, pliki motywu, mu-plugins |
| Przekierowanie zawsze, także przy wejściu do kokpitu | Zmienione adresy siteurl i home albo przejęte DNS domeny |
Ustawienia → Ogólne, tabela wp_options, stałe WP_HOME i WP_SITEURL w wp-config.php, panel rejestratora domeny |
| W Google podstrony z lekami, kasynem, podróbkami albo japońskimi znakami | Spam SEO: atakujący podpina pod Twoją domenę tysiące stron reklamowych | Search Console, wyszukiwanie site:, wp_posts, nowe katalogi w plikach, obce mapy witryny |
| Administrator, którego nie znasz | Przejęte konto, luka we wtyczce pozwalająca założyć użytkownika albo włączona rejestracja z rolą administratora | Użytkownicy, tabele wp_users i wp_usermeta, hasła aplikacji, opcje users_can_register i default_role |
| Klienci sklepu zgłaszają nieautoryzowane transakcje albo na stronie zamówienia pojawia się dodatkowy formularz karty | Skrypt przechwytujący dane płatności, wstrzyknięty w stronę zamówienia | Kod strony zamówienia (narzędzia przeglądarki → Sieć: żądania do obcych domen), wp_options, pliki motywu i wtyczki płatności |
| Czerwona plansza w Chrome, że witryna jest niebezpieczna | Google Bezpieczne przeglądanie wykryło malware, phishing albo szkodliwe pliki | Search Console → Problemy dotyczące bezpieczeństwa, Transparency Report |
| Hosting zawiesił konto albo zablokował wysyłkę poczty | Skrypt na koncie rozsyła spam lub atakuje inne serwery | Logi i powiadomienie hostingu, pliki PHP w uploads, cron serwera |
| Maile z firmowej domeny lądują w spamie | Adres serwera lub domena trafiły na czarną listę po wysyłce spamu ze strony | Hosting, skrypty wysyłające pocztę, nagłówki odrzuconych wiadomości |
| Strona nagle zwolniła, hosting zgłasza przekroczenie limitów procesora | Koparka kryptowalut, skrypt spamujący albo atak prowadzony z Twojego konta | Procesy w panelu hostingu, ostatnio zmienione pliki |
W katalogu głównym pliki o nazwach podobnych do systemowych, np. wp-l0gin.php |
Backdoor, czyli tylne wejście dla atakującego | wp core verify-checksums --include-root |
Przekierowania tylko na telefonie albo tylko z Google
To najbardziej mylący objaw, bo właściciel strony go nie widzi. Złośliwy kod przekierowuje tylko część ruchu: telefony, wejścia z wyników Google, gości niezalogowanych. Często zapamiętuje też gościa (ciasteczkiem albo adresem IP) i przekierowuje go tylko raz. Klient zgłasza problem, Ty sprawdzasz na komputerze, na którym jesteś zalogowany do WordPressa, i widzisz normalną stronę.
Żeby zobaczyć to, co klient, otwórz stronę na telefonie w trybie incognito, na danych komórkowych zamiast firmowego Wi-Fi, i wejdź na nią z wyniku wyszukiwania Google, a nie przez wpisanie adresu. Dokładniejszy test z wiersza poleceń opisujemy niżej.
Spam w wynikach Google
Wpisz w Google site:twojadomena.pl i przejrzyj kilka stron wyników. Szukaj adresów, których nie tworzyłeś: losowych katalogów, nazw leków, tytułów z japońskimi znakami. Atakujący często pokazują spam tylko robotom Google, a ludziom stronę 404 albo normalną treść. Google opisuje ten schemat w poradniku o ataku z japońskimi słowami kluczowymi. Podejrzane adresy sprawdź w Search Console narzędziem Sprawdzanie adresu URL, które pokazuje, co faktycznie widzi Googlebot.
Przy tym typie ataku zajrzyj też w Search Console do Ustawienia → Użytkownicy i uprawnienia. Nieznany właściciel usługi to mocny sygnał włamania: atakujący dodaje się, żeby zgłaszać własne mapy witryny.
Ostrzeżenie o niebezpiecznej witrynie i mail od hostingu
Czerwona plansza w Chrome z ostrzeżeniem, że witryna może być niebezpieczna, oznacza, że adres trafił na listę Google Bezpieczne przeglądanie. Stan sprawdzisz w Google Transparency Report. Z tej listy korzystają też inne popularne przeglądarki, więc ostrzeżenie widzi większość odwiedzających. Mail od hostingu o zawieszeniu konta zwykle zawiera listę plików uznanych za złośliwe. Zachowaj go: to gotowe punkty startowe do analizy.
Drzewko diagnozy: włamanie czy zwykła awaria?
- Strona w ogóle się nie wyświetla (biały ekran, „błąd krytyczny”, błąd 500).
- Pojawiło się po aktualizacji, zmianie PHP lub instalacji wtyczki? To najpewniej awaria, nie włamanie. Zacznij od poradnika błąd krytyczny w witrynie WordPress.
- Nikt niczego nie zmieniał, a w plikach są nowe pliki PHP z ostatnich dni? Podejrzenie włamania, przejdź do sprawdzania niżej.
- Strona przekierowuje na obcą domenę.
- Zawsze, także przy wejściu do
/wp-admin/? Sprawdź adresy w Ustawienia → Ogólne, stałe wwp-config.phpi DNS domeny. - Tylko na telefonie, tylko z Google, tylko raz? Włamanie z przekierowaniem warunkowym.
- Zawsze, także przy wejściu do
- Strona działa, ale coś jest nie tak w Google (obce podstrony, ostrzeżenie w wynikach). Włamanie typu spam SEO, nawet jeśli na stronie nic nie widać.
- Strona działa i wygląda normalnie, ale hosting coś zgłasza (spam, procesor, wirus). Włamanie, które nie dotyka wyglądu strony. Poproś hosting o listę plików i godziny zdarzeń.
- Nic z powyższych, strona po prostu działa źle. Przejdź do ogólnej diagnozy: co zrobić, gdy strona WordPress nie działa.
Jak sprawdzić, czy strona ma wirusa
Skaner online i testy bez dostępu technicznego
Ścieżka: każdy. Cztery testy, każdy zajmuje kilka minut:
- Transparency Report — wpisz domenę w raporcie Bezpieczne przeglądanie. Wynik „nie znaleziono niebezpiecznych treści” nie wyklucza infekcji, tylko informuje, że Google jej jeszcze nie oznaczył.
- Wyszukiwanie
site:— jak w sekcji wyżej. Dodaj słowa typowe dla spamu, np.site:twojadomena.pl casinoalbosite:twojadomena.pl viagra. - Search Console — Bezpieczeństwo i ręczne działania → Problemy dotyczące bezpieczeństwa (po zalogowaniu raport otworzysz też bezpośrednio pod adresem search.google.com/search-console/security-issues). Jeśli Google coś wykrył, zobaczysz tu typ problemu (np. „Atak hakerów: wstrzyknięty kod”) i przykładowe adresy.
- Skaner malware online — dokumentacja WordPressa w artykule FAQ My site was hacked wymienia Sucuri SiteCheck i VirusTotal. Skanery z zewnątrz widzą tylko to, co serwer pokaże im publicznie, więc infekcji ukrytej przed nimi nie wykryją.
Test ukrytych przekierowań poleceniem curl
Ścieżka: każdy, kto nie boi się okna terminala. Polecenie curl pobiera stronę i pozwala podać się za telefon, Googlebota albo gościa z Google. W Windowsie 10 i 11 jest wbudowane: w PowerShellu wpisz curl.exe (sam curl bywa tam aliasem innego polecenia), /dev/null zamień na NUL i każde polecenie wpisz w jednej linii, bez ukośników \ na końcach linii.
# 1. Zwykła przeglądarka na komputerze
curl -s -o /dev/null -w "%{http_code} %{size_download} %{redirect_url}\n" https://twojadomena.pl/
# 2. Telefon (iPhone)
curl -s -o /dev/null -w "%{http_code} %{size_download} %{redirect_url}\n" \
-A "Mozilla/5.0 (iPhone; CPU iPhone OS 18_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1" \
https://twojadomena.pl/
# 3. Gość, który kliknął wynik w Google
curl -s -o /dev/null -w "%{http_code} %{size_download} %{redirect_url}\n" \
-e "https://www.google.com/" https://twojadomena.pl/
# 4. Robot Google
curl -s -o /dev/null -w "%{http_code} %{size_download} %{redirect_url}\n" \
-A "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" \
https://twojadomena.pl/
# 5. Telefon, który kliknął wynik w Google (najczęstszy wariant przekierowania)
curl -s -o /dev/null -w "%{http_code} %{size_download} %{redirect_url}\n" \
-A "Mozilla/5.0 (iPhone; CPU iPhone OS 18_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.0 Mobile/15E148 Safari/604.1" \
-e "https://www.google.com/" https://twojadomena.pl/
Każde polecenie wypisuje kod odpowiedzi, rozmiar strony w bajtach i adres przekierowania. Zdrowa strona zwraca we wszystkich testach ten sam wynik: zwykle 200 i podobny rozmiar. Kod 301 na Twoją własną domenę (np. z wersji bez www na www albo z http na https) też jest normalny. Alarmujące są: przekierowanie 301 lub 302 na obcą domenę, różne wyniki w różnych wariantach oraz wyraźnie większa strona dla Googlebota niż dla przeglądarki (robot dostaje wtedy dodatkową treść, zwykle spam).
Ograniczenie testu: część złośliwych skryptów przekierowuje dopiero JavaScriptem w przeglądarce, a część sprawdza, czy zapytanie naprawdę przychodzi z serwerów Google. Czysty wynik curl niczego nie wyklucza, ale podejrzany wystarczy, żeby uznać stronę za zainfekowaną.
Wtyczka skanująca: co potrafi, a czego nie
Ścieżka: każdy z dostępem do kokpitu. Wtyczki takie jak Wordfence, Sucuri Security czy Quttera (wymienia je dokumentacja WordPress.org) sprawdzają integralność plików, zwykle przynajmniej rdzenia, i szukają znanych wzorców złośliwego kodu. To dobre narzędzie wstępne, z trzema zastrzeżeniami:
- działa wewnątrz zainfekowanej instalacji, a część malware’u celowo ukrywa się przed popularnymi skanerami;
- nie zawsze znajdzie kod w bazie danych, w zadaniach cron serwera, w plikach
.user.iniczy na innej stronie na tym samym koncie; - pokazuje objawy, ale nie mówi, którędy weszła infekcja, a bez tego infekcja wróci.
Zainstaluj jedną wtyczkę, a nie trzy naraz. Kilka skanerów jednocześnie potrafi przeciążyć hosting i położyć stronę, która i tak ledwo działa.
Pierwsza godzina: ogranicz szkody i zabezpiecz dowody
Ścieżka: każdy, fragmenty z kodem dla FTP/SSH. W pierwszej godzinie chodzi o dwie rzeczy: atakujący nie może dalej działać, a Ty nie możesz stracić śladów, które powiedzą, którędy wszedł.
Kopia zainfekowanej strony i logi
Kopia zainfekowanej strony to nie kopia do przywrócenia, tylko materiał do analizy. Pozwoli ustalić, co zmienił atakujący, i odzyskać treści, gdyby czyszczenie coś uszkodziło. Na hostingu z SSH zrobisz ją tak (ścieżkę dostosuj: w DirectAdmin to zwykle ~/domains/twojadomena.pl/public_html, w cPanelu ~/public_html):
# katalog na materiał z incydentu, poza katalogiem publicznym
mkdir -p ~/incydent-2026-10-12
cd ~/domains/twojadomena.pl/public_html
# pliki strony
tar -czf ~/incydent-2026-10-12/pliki.tar.gz .
# baza danych (WP-CLI)
wp db export ~/incydent-2026-10-12/baza.sql
Od razu pobierz oba pliki na swój komputer albo do zewnętrznego magazynu (np. przez SFTP) i usuń je z serwera: na przejętym koncie atakujący może je zmienić albo skasować, a duże archiwum zjada limit miejsca. Archiwum z malware’em nie rozpakowuj na komputerze. Jeśli antywirus je blokuje, zapakuj je w archiwum z hasłem. Zrzut bazy zawiera dane klientów, więc przechowuj go zaszyfrowany.
Pobierz też logi dostępu i błędów z panelu hostingu. Na wielu hostingach współdzielonych logi są przechowywane tylko kilka dni, a to w nich widać żądania POST do dziwnych plików i adres, z którego atakujący wgrał backdoor.
Czy wyłączyć stronę na czas czyszczenia
Wyłącz, jeśli strona przekierowuje gości na podejrzane domeny, wyświetla fałszywe okna logowania albo jest sklepem, w którym mogą być przechwytywane dane płatności. Jeśli objawem jest wyłącznie spam w Google, możesz czyścić stronę bez wyłączania.
Najbezpieczniej wyłączyć ją kodem 503, który mówi Google „przerwa techniczna, wróć później”. Poniższe linie na samej górze pliku .htaccess (Apache, LiteSpeed) wpuszczają tylko Twój adres IP, a pozostałym pokazują 503:
# Przerwa techniczna: wszyscy poza Twoim IP dostają 503
RewriteEngine On
RewriteCond %{REMOTE_ADDR} !^203\.0\.113\.45$
RewriteRule ^ - [R=503,L]
Zamiast 203\.0\.113\.45 wpisz swój adres IP (kropki poprzedź ukośnikiem wstecznym). Sprawdź go na dowolnej stronie, która wyświetla adres IP, z tej samej sieci, z której będziesz pracować. Jeśli strona stoi za Cloudflare albo Twoje łącze używa IPv6, ta reguła zablokuje także Ciebie. Wtedy włącz przerwę w panelu Cloudflare albo poproś o nią hosting. Na serwerach z nginx plik .htaccess nie działa. Wtedy poproś hosting o tymczasowe wyłączenie domeny. Przerwa trwająca kilka godzin nie szkodzi pozycjom w Google, kilka dni już tak.
Hasła i dostępy: teraz i jeszcze raz po czyszczeniu
Teraz zmień hasła do panelu hostingu, kont FTP/SFTP, poczty w domenie i kont administratorów WordPressa. Hasło do bazy danych zmienisz po czyszczeniu, razem z wpisem w wp-config.php. Dokumentacja WordPressa zaleca zmianę wszystkich haseł jeszcze raz po wyczyszczeniu strony, bo te z pierwszej godziny mogły zostać przechwycone przez backdoor, który wtedy jeszcze działał.
Atakujący z dostępem do konta hostingu zostawia sobie zwykle więcej niż jedno wejście. W panelu hostingu przejrzyj:
- listę kont FTP: usuń te, których nie zakładałeś;
- klucze SSH (plik
~/.ssh/authorized_keysalbo sekcja kluczy SSH w panelu): zostaw tylko swoje; - użytkowników baz danych: każdy poza tym z
wp-config.phpwymaga wyjaśnienia; - przekierowania poczty i autorespondery: atakujący lubi kopiować sobie maile do resetu haseł;
- konto u rejestratora domeny i panel DNS: zmień hasło, włącz logowanie dwuskładnikowe i sprawdź, czy rekordy DNS wskazują na Twój serwer.
Przeskanuj też antywirusem komputer, z którego logujesz się do hostingu i WordPressa. Dokumentacja WordPressa zwraca uwagę, że część włamań zaczyna się od kradzieży haseł z komputera właściciela.
Czy musisz zgłosić włamanie do UODO
Ścieżka: każdy. Włamanie na stronę staje się naruszeniem ochrony danych osobowych, jeśli atakujący mógł uzyskać dostęp do danych ludzi, zmienić je albo usunąć. Na typowej stronie firmowej to między innymi:
- konta klientów i zamówienia w sklepie WooCommerce (imiona, adresy, telefony);
- wiadomości z formularzy kontaktowych zapisywane w bazie przez wtyczkę formularzy;
- listy zapisów na newsletter, konta użytkowników, zgłoszenia rekrutacyjne z CV.
Najpoważniejszy scenariusz to sklep, w którym na stronie zamówienia działał skrypt przechwytujący dane kart. To z reguły naruszenie wysokiego ryzyka, czyli oprócz zgłoszenia do UODO trzeba zawiadomić klientów (art. 34). Powiadom też operatora płatności, bo może zablokować skradzione karty i pomóc ustalić, od kiedy trwał wyciek.
Jeśli stroną opiekuje się zewnętrzna firma, jest ona podmiotem przetwarzającym i ma obowiązek powiadomić Cię o naruszeniu bez zbędnej zwłoki. Decyzja o zgłoszeniu do UODO należy jednak do Ciebie jako administratora danych. Incydent możesz też dobrowolnie zgłosić do zespołu CERT Polska przez formularz incydent.cert.pl. Firmy objęte przepisami o krajowym systemie cyberbezpieczeństwa mają osobne obowiązki raportowania.
Samodzielnie czy z fachowcem — test 5 pytań
Ścieżka: każdy. Czyszczenie WordPressa da się przeprowadzić samodzielnie, jeśli masz dostęp do plików i bazy i wiesz, co robisz. Odpowiedz szczerze:
- Czy to sklep albo strona z kontami klientów, a atakujący mógł dostać się do ich danych?
- Czy hosting zawiesił konto albo Chrome pokazuje czerwoną planszę?
- Czy masz dostęp do FTP lub SSH i do bazy danych (phpMyAdmin) i potrafisz z nich korzystać?
- Czy masz kopię sprzed włamania i wiesz, kiedy włamanie nastąpiło?
- Czy to drugie włamanie w ciągu kilku miesięcy?
Jeśli na pytanie 1, 2 lub 5 odpowiadasz „tak” albo na pytanie 3 lub 4 „nie”, przestań naprawiać sam. Każda godzina z przekierowaniem na spam to utracone zaufanie klientów i sygnał dla Google, a nieudane czyszczenie zwykle kończy się powrotem infekcji po kilku dniach. Opisz objawy w formularzu pomocy po włamaniu na stronę WordPress: w godzinach dyżuru (pn–pt 8:00–20:00, sob 10:00–16:00) odezwiemy się w ciągu godziny, a przed rozpoczęciem pracy podamy stałą cenę.
Jak odwirusować WordPress: usuwanie malware krok po kroku
Ścieżka: FTP/SSH. Kolejność ma znaczenie: najpierw wymieniasz w całości to, co da się wymienić (rdzeń, wtyczki, motywy z oficjalnych źródeł), a potem szukasz ręcznie w miejscach, które są unikalne dla Twojej strony: uploads, konfiguracji i bazie danych.
Rdzeń WordPressa: weryfikacja i podmiana plików
WP-CLI porównuje pliki rdzenia z sumami kontrolnymi opublikowanymi przez WordPress.org (dokumentacja polecenia: wp core verify-checksums):
wp core version --extra
wp core verify-checksums --include-root
Komunikat File doesn't verify against checksum oznacza plik rdzenia zmieniony przez kogoś. Taki wynik kończy się błędem. Pliki dodane przez atakującego (File should not exist) to tylko ostrzeżenia: nawet przy kilku backdoorach w wp-includes polecenie skończy się linią Success: WordPress installation verifies against checksums. Sprawdziliśmy to na WordPressie 7.1.3. Czytaj więc całą listę ostrzeżeń, a nie tylko ostatnią linię.
Polecenie nie sprawdza wp-config.php, .htaccess, .maintenance ani wp-content, więc te miejsca przejrzysz ręcznie (niżej). W katalogu głównym normalne bywają pliki dodane przez Ciebie albo hosting, np. plik weryfikacyjny Google (google*.html) czy .user.ini, ale każdy z nich otwórz i sprawdź.
Plików rdzenia nie czyścisz ręcznie: podmieniasz je na świeże w tej samej wersji i języku. Dokumentacja WordPressa ostrzega, że reinstalacja starszej albo nowszej wersji najpewniej położy stronę. Najpewniej jest usunąć katalogi wp-admin i wp-includes w całości i pobrać je na nowo, bo wtedy znikają też pliki dodane przez atakującego:
# wersja i język obecnej instalacji (czytane z pliku, bez ładowania WordPressa)
WERSJA=$(wp core version)
JEZYK=$(wp core version --extra | awk -F': *' '/Package language/ {print $2}')
echo "$WERSJA $JEZYK"
# usunięcie starych katalogów rdzenia i pobranie świeżych (bez wp-content)
rm -rf wp-admin wp-includes
wp core download --version="$WERSJA" --locale="$JEZYK" --skip-content --force
# ponowna weryfikacja: zostaną tylko obce pliki w katalogu głównym
wp core verify-checksums --include-root
Sprawdź, czy echo wypisało wersję i język (np. 7.1.3 pl_PL), zanim usuniesz katalogi. Pliki w katalogu głównym oznaczone jako File should not exist po obejrzeniu usuń ręcznie.
Bez SSH (tylko FTP). Wersję odczytasz w Kokpit → Aktualizacje. Pobierz archiwum dokładnie tej wersji z archiwum wydań WordPressa, rozpakuj je na komputerze, a potem przez FTP usuń z serwera katalogi wp-admin i wp-includes i wgraj je z archiwum. Nie używaj przycisku „Ponownie zainstaluj wersję…” w kokpicie: nadpisuje pliki, ale nie usuwa tych dodanych przez atakującego. Pliki w katalogu głównym (poza wp-config.php i .htaccess) porównaj z archiwum. Tych, których w nim nie ma, a nie potrafisz wyjaśnić, pozbądź się po obejrzeniu.
Wtyczki i motywy: tylko z oficjalnych źródeł
wp --skip-plugins --skip-themes plugin list --fields=name,status,version,update
wp --skip-plugins --skip-themes plugin verify-checksums --all
Dla wtyczek z repozytorium WordPress.org polecenie pokaże pliki zmienione, dodane i brakujące. Wtyczek płatnych (np. wersji „Pro”) nie zweryfikuje, bo ich sum kontrolnych nie ma w repozytorium. Te pobierz świeżo z konta u producenta i wgraj w miejsce starego katalogu. Bez WP-CLI zmienione pliki wtyczek pokaże skan wtyczki skanującej.
Zasada: każdą wtyczkę i motyw usuń i zainstaluj od nowa. Wtyczki z repozytorium podmienisz poleceniem wp plugin install nazwa-wtyczki --force, a potem ponownie uruchomisz weryfikację. Przez FTP: usuń katalog wtyczki i wgraj świeży, pobrany z jej strony na wordpress.org. Motyw potomny (child theme) zawiera Twoje własne zmiany, więc jego pliki, zwłaszcza functions.php, header.php i footer.php, przejrzyj ręcznie.
Częstym źródłem infekcji są wtyczki i motywy w wersji „nulled”, czyli płatne dodatki pobrane za darmo z nieoficjalnych stron. Bywają sprzedawane razem z wbudowanym backdoorem. Jeśli masz takie na stronie, czyszczenie bez ich usunięcia nie ma sensu: kup licencję albo zastąp wtyczkę inną.
Usuń też wtyczki nieaktywne i te, których nie potrzebujesz, w szczególności menedżery plików i wtyczki do wstawiania kodu. Jeśli ich nie instalowałeś, mógł to zrobić atakujący.
Katalog uploads, mu-plugins, .htaccess i wp-config.php
W tych miejscach najczęściej zostają backdoory, bo nie obejmuje ich żadna weryfikacja sum kontrolnych. Polecenia uruchamiasz w katalogu głównym WordPressa:
# 1. PHP w uploads: tam nie powinno być żadnego pliku PHP
find wp-content/uploads -type f -iname "*.php*"
# 2. pliki PHP zmienione w ostatnich 30 dniach, od najnowszych
# (cache pomijamy, bo i tak usuniesz go w całości, patrz niżej)
find . -type f -name "*.php" -mtime -30 -not -path "./wp-content/cache/*" \
-printf "%TY-%Tm-%Td %TH:%TM %p\n" | sort -r | head -50
# 2a. to samo według czasu zmiany (ctime), którego nie cofnie polecenie touch
find . -type f -name "*.php" -ctime -30 -not -path "./wp-content/cache/*" \
-printf "%CY-%Cm-%Cd %CH:%CM %p\n" | sort -r | head -50
# 3. typowe wzorce zaciemnionego kodu
grep -rlE "eval\s*\(\s*(base64_decode|gzinflate|gzuncompress|str_rot13)" --include="*.php" .
# 3a. kolejne wzorce: assert i create_function na danych z żądania, funkcje
# wywoływane z $_POST/$_COOKIE, długie ciągi \x.. (szukamy tylko w wp-content,
# bo rdzeń podmieniasz w całości, a w nim takie ciągi bywają legalne)
grep -rlE '(assert\s*\(\s*\$_|create_function\s*\(|\$_(POST|GET|REQUEST|COOKIE)\s*\[[^]]*\]\s*\(|([\]x[0-9a-fA-F]{2}){8,})' \
--include="*.php" wp-content
# 4. dołączanie plików o nietypowych rozszerzeniach (np. PHP ukryty w .ico)
grep -rnE "include(_once)?\s*\(?\s*[\"'][^\"']+\.(ico|png|jpg|gif|txt)[\"']" --include="*.php" .
find . -type f -name "*.ico" -not -name "favicon.ico"
# 5. wszystkie pliki .htaccess w drzewie strony
find . -name ".htaccess" -printf "%TY-%Tm-%Td %p\n"
# 6. wtyczki obowiązkowe i drop-iny
ls -la wp-content/mu-plugins/
wp --skip-plugins --skip-themes plugin list --status=must-use
wp --skip-plugins --skip-themes plugin list --status=dropin
# 7. dopisywanie kodu do każdego żądania PHP (.user.ini, php.ini)
find . \( -name ".user.ini" -o -name "php.ini" \) \
-exec grep -HnE "auto_(prepend|append)_file" {} +
Jak czytać wyniki:
- PHP w
uploadsto praktycznie zawsze backdoor. Wyjątkiem bywają pliki zabezpieczające niektórych wtyczek (np. pustyindex.php), ale każdy z nich otwórz i sprawdź. - Daty modyfikacji pomagają ustalić dzień włamania, ale atakujący potrafią je podrobić. Plik ze „starą” datą też może być zainfekowany. Czas zmiany (
ctime) ustawia system i nie da się go cofnąć poleceniemtouch, ale zmienia się też przy przywracaniu kopii czy zmianie uprawnień, więc traktuj go jako wskazówkę. - Wzorce
eval,base64_decodei ciągi\x..pojawiają się czasem w legalnych wtyczkach, ale ich połączenie, wywołanie funkcji wprost z$_POSTalbo$_COOKIElub długie ciągi przypadkowych znaków to niemal zawsze malware. mu-plugins, czyli wtyczki obowiązkowe, ładują się zawsze i nie widać ich na zwykłej liście wtyczek. Zostaw tylko te, które potrafisz przypisać do hostingu lub znanej wtyczki.- Drop-iny to pliki w
wp-content, które WordPress ładuje automatycznie:advanced-cache.php,object-cache.php,db.php, a takżemaintenance.php,fatal-error-handler.phpczyphp-error.php. Pierwsze trzy są normalne przy wtyczkach cache. Każdy drop-in, którego nie potrafisz przypisać do znanej wtyczki, obejrzyj. .user.inialbophp.iniz dyrektywąauto_prepend_filelubauto_append_filedokleja wskazany plik PHP do każdego żądania. Nie wykryje tego żadna weryfikacja sum WordPressa. Legalnie robi tak zapora Wordfence (plikwordfence-waf.php). Jeśli dyrektywa wskazuje plik, którego nie rozpoznajesz, usuń ją i ten plik. Zmiana zaczyna działać po kilku minutach, bo PHP domyślnie trzyma.user.iniw pamięci przez 300 sekund. Sprawdź też ustawienia PHP w panelu hostingu, gdzie da się wpisać tę samą dyrektywę..htaccessw głównym katalogu powinien zawierać blok# BEGIN WordPressi reguły Twoich wtyczek. Reguły z%{HTTP_USER_AGENT}lub%{HTTP_REFERER}kierujące na obce domeny to przekierowanie warunkowe (przykład niżej). Pliki.htaccessw podkatalogach, których pochodzenia nie potrafisz wyjaśnić, usuń.wp-config.phpotwórz i przeczytaj od góry do dołu. Podejrzane są dopisane linieincludelubrequirez dziwnymi ścieżkami, stałeWP_HOMEiWP_SITEURLz obcą domeną oraz kod przed<?phplub po liniirequire_once ABSPATH . 'wp-settings.php';.
Tak wygląda typowe przekierowanie warunkowe dopisane przez atakującego do .htaccess (domena jest przykładowa):
RewriteCond %{HTTP_REFERER} (google|bing|yahoo) [NC]
RewriteCond %{HTTP_USER_AGENT} (android|iphone|mobile) [NC]
RewriteRule ^(.*)$ https://obca-domena.example/ [R=302,L]
Trzy linie wystarczą, żeby telefony wchodzące z wyszukiwarki trafiały na spam, a Ty przy wpisaniu adresu na komputerze widział normalną stronę.
Baza danych: wp_options, wp_posts i wp_users
Najpierw sprawdź adresy strony, ustawienia rejestracji i przeszukaj bazę przez WP-CLI. wp db search tylko czyta, niczego nie zmienia:
wp --skip-plugins --skip-themes option get siteurl
wp --skip-plugins --skip-themes option get home
wp --skip-plugins --skip-themes option get admin_email
# rejestracja: na stronie bez kont klientów oczekiwane 0
wp --skip-plugins --skip-themes option get users_can_register
# domyślna rola: subscriber (w WooCommerce customer), nigdy administrator
wp --skip-plugins --skip-themes option get default_role
wp --skip-plugins --skip-themes db search "<script" wp_options --one_line
wp --skip-plugins --skip-themes db search "base64_decode" --all-tables-with-prefix --one_line
wp --skip-plugins --skip-themes user list --role=administrator --fields=ID,user_login,user_email,user_registered
To samo zrobisz w phpMyAdmin, w zakładce SQL. Zapytania poniżej są tylko do odczytu. Prefiks wp_ zamień na swój (zmienna $table_prefix w wp-config.php):
-- opcje z kodem JavaScript lub zaciemnionym PHP oraz kluczowe ustawienia
SELECT option_id, option_name, LEFT(option_value, 150) AS fragment
FROM wp_options
WHERE option_value LIKE '%<script%'
OR option_value LIKE '%eval(%'
OR option_value LIKE '%base64_decode%'
OR option_name IN ('siteurl', 'home', 'admin_email', 'users_can_register', 'default_role');
-- wpisy i strony ze skryptami, ramkami lub ukrytymi linkami
SELECT ID, post_type, post_status, post_modified, post_title
FROM wp_posts
WHERE post_content LIKE '%<script%'
OR post_content LIKE '%<iframe%'
OR post_content LIKE '%display:none%'
ORDER BY post_modified DESC
LIMIT 100;
-- wszyscy administratorzy, od najnowszego
SELECT u.ID, u.user_login, u.user_email, u.user_registered
FROM wp_users u
JOIN wp_usermeta m ON m.user_id = u.ID
WHERE m.meta_key = 'wp_capabilities'
AND m.meta_value LIKE '%administrator%'
ORDER BY u.user_registered DESC;
Nie każdy wynik to infekcja. Wtyczki do analityki, czatów i ciasteczek trzymają w wp_options legalne skrypty, a w treściach bywają osadzone mapy czy filmy. Szukasz skryptów ładowanych z domen, których nie znasz, i kodu zaciemnionego, np. ciągów wywołań String.fromCharCode czy atob.
Porównaj listę administratorów z SQL z listą w kokpicie (Użytkownicy → Administrator). Jeśli zapytanie pokazuje konto, którego nie widać w kokpicie, złośliwy kod ukrywa je przed Tobą. Szukaj go w mu-plugins, w functions.php motywu i w wp_options.
Przy spamie SEO sprawdź też, czy w wp_posts nie przybyło setek wpisów z ostatnich dni. Zanim cokolwiek usuniesz z bazy, upewnij się, że masz jej kopię. Przed usunięciem nieznanego administratora zobacz jego treści: wp post list --author=ID --post_type=any --post_status=any. Jeśli to spam, usuń konto razem z nimi poleceniem wp user delete ID. Opcję --reassign=TWOJE_ID dodaj tylko wtedy, gdy konto miało legalne treści, bo inaczej spam zostanie opublikowany pod Twoim nazwiskiem.
Sprawdź też hasła aplikacji wszystkich administratorów. Pozwalają logować się przez API z pominięciem zwykłego hasła, a zmiana hasła ich nie unieważnia:
# hasła aplikacji każdego administratora
wp user list --role=administrator --field=ID | xargs -I % wp user application-password list %
# usunięcie wszystkich haseł aplikacji jednego użytkownika
wp user application-password delete ID --all
Zadania cron WordPressa i serwera
Backdoor często ma plan awaryjny: zadanie, które co kilka minut odtwarza usunięty plik. Sprawdź oba poziomy:
# zadania WordPressa
wp --skip-plugins --skip-themes cron event list --fields=hook,next_run_relative,recurrence
# zadania serwera (SSH)
crontab -l
Na liście zadań WordPressa zwykłe nazwy to wp_version_check, wp_update_plugins, wp_privacy_delete_old_export_files i zadania Twoich wtyczek. Nazwa z losowych znaków albo zadanie, którego nie da się przypisać do żadnej wtyczki, jest podejrzane. Usuniesz je przez wp cron event delete nazwa_zadania. W panelu hostingu zadania serwera znajdziesz w sekcji Cron Jobs (cPanel, DirectAdmin). Polecenie, które pobiera coś z obcego adresu (wget, curl) albo uruchamia plik z uploads lub /tmp, to niemal na pewno infekcja.
Cache i CDN: usuń zapisane kopie stron
Wtyczka cache, serwer LiteSpeed i CDN (np. Cloudflare) przechowują gotowe wersje stron. Po czyszczeniu plików dalej mogą serwować HTML z wstrzykniętym skryptem, a wtedy test curl i weryfikacja Google pokażą infekcję, której w plikach już nie ma. W katalogu wp-content/cache malware też potrafi się schować.
# po zrobieniu kopii: usuń całą zawartość katalogu cache
rm -rf wp-content/cache/*
# przy wtyczce LiteSpeed Cache: wyczyść cache serwera
wp litespeed-purge all
Bez SSH użyj przycisku czyszczenia w ustawieniach wtyczki cache. Jeśli korzystasz z Cloudflare, wyczyść też cały cache w jego panelu (Purge Everything).
Kiedy lepiej przywrócić kopię albo postawić stronę od nowa
Przywrócenie kopii jest najszybsze, jeśli spełnia dwa warunki: kopia pochodzi sprzed włamania (a włamanie bywa wcześniejsze od pierwszych objawów nawet o tygodnie) i po przywróceniu od razu zamykasz lukę. Przywrócona strona ze starą, dziurawą wtyczką zostanie zainfekowana ponownie, często tą samą drogą.
Postawienie strony od nowa oznacza czystą instalację WordPressa, świeże wtyczki i motyw, nowy wp-config.php oraz przeniesienie tylko treści: przejrzanej bazy i plików multimediów bez PHP. Przy rozległej infekcji to bywa pewniejsze niż wyszukiwanie każdego zainfekowanego pliku.
Po czyszczeniu: hasła, klucze SALT, sesje i 2FA
Ścieżka: FTP/SSH, część dla każdego. Atakujący może mieć ważne ciasteczka logowania do kont, których haseł nie zmieniłeś. Zmiana kluczy w wp-config.php unieważnia wszystkie sesje naraz i wylogowuje wszystkich użytkowników, co potwierdza dokumentacja WordPressa:
# nowe klucze i sole w wp-config.php (wylogowuje wszystkich)
wp config shuffle-salts
# nowe losowe hasło dla Twojego konta; e-mail informuje tylko o zmianie,
# samo hasło wyświetli się w terminalu dzięki --show-password
# (TWOJ_LOGIN zamień na swój login; lista: wp user list --role=administrator)
wp user reset-password TWOJ_LOGIN --show-password
Bez SSH nowe klucze wygenerujesz w generatorze WordPress.org i wkleisz w miejsce ośmiu linii od define( 'AUTH_KEY' do define( 'NONCE_SALT' w wp-config.php. Potem zmień hasło do bazy danych w panelu hostingu i w wp-config.php, a na koniec jeszcze raz hasła do hostingu, FTP i WordPressa.
Dokumentacja WordPressa zaleca reset haseł wszystkich użytkowników, a w szczególności administratorów. W sklepie oznacza to także klientów, jeśli atakujący mógł skopiować bazę z hashami haseł. Polecenie poniżej ustawia klientom losowe hasła bez wysyłania standardowego maila o zmianie, więc wyślij im własną wiadomość z instrukcją „ustaw nowe hasło przez Nie pamiętasz hasła?”. Najlepiej połącz ją z ewentualnym zawiadomieniem z art. 34 RODO.
# redaktorzy i autorzy: losowe nowe hasła z powiadomieniem e-mail
wp user list --role__in=editor,author --field=ID | xargs -n 100 wp user reset-password
# klienci sklepu: losowe hasła bez maila (komunikat wysyłasz sam)
wp user list --role=customer --field=ID | xargs -n 100 wp user reset-password --skip-email
Wymień też klucze, które WordPress przechowuje dla innych usług, bo atakujący z dostępem do bazy mógł je skopiować: klucze REST API WooCommerce (WooCommerce → Ustawienia → Zaawansowane → REST API, usuń nieznane), klucze bramek płatności, hasło SMTP we wtyczce pocztowej i klucze integracji (Google, CRM, newsletter).
Dla kont administratorów włącz logowanie dwuskładnikowe. Do wp-config.php dopisz blokadę edytora plików w kokpicie (opisaną w dokumentacji Hardening WordPress), a w katalogu wp-content/uploads utwórz plik .htaccess blokujący wykonywanie PHP:
// wp-config.php: wyłącza edytor motywów i wtyczek w kokpicie
define( 'DISALLOW_FILE_EDIT', true );
# wp-content/uploads/.htaccess (Apache 2.4, LiteSpeed)
<FilesMatch "\.(?i:php[0-9]?|phtml|phar)$">
Require all denied
</FilesMatch>
Na koniec zaktualizuj rdzeń, wtyczki i motywy oraz sprawdź wersję PHP. WordPress 7.x uruchomi się jeszcze na PHP 7.4, ale WordPress.org zaleca PHP 8.3 lub nowsze. PHP 8.1 i starsze nie dostają już poprawek bezpieczeństwa, a PHP 8.2 dostaje je tylko do 31 grudnia 2026 r. (harmonogram wsparcia na php.net).
Jak zdjąć ostrzeżenie Google po włamaniu
Ścieżka: każdy z dostępem do Search Console. Ostrzeżenie nie zniknie samo po wyczyszczeniu strony. Procedura według pomocy Search Console:
- Upewnij się, że strona jest czysta. Wyczyść cache wtyczki, serwera i CDN, a potem powtórz test curl i wyszukiwanie
site:. Przykładowe adresy z raportu sprawdź narzędziem Sprawdzanie adresu URL. - Usuń nieznanych właścicieli i obce mapy witryny. Ustawienia → Użytkownicy i uprawnienia oraz Indeksowanie → Mapy witryn. Usuń też plik weryfikacyjny, którym atakujący potwierdził własność.
- Zadbaj, żeby adresy ze spamem zwracały 404 lub 410. Wtedy wypadną z indeksu. Narzędzie Usunięcia ukryje je szybciej, ale tylko tymczasowo.
- Poproś o sprawdzenie. Bezpieczeństwo i ręczne działania → Problemy dotyczące bezpieczeństwa → „Poproś o sprawdzenie”. Opisz, co było problemem, co zrobiłeś i jaki jest efekt.
- Czekaj na decyzję. Google podaje, że sprawdzenie trwa zwykle od kilku dni do kilku tygodni. Nie wysyłaj kolejnej prośby, zanim przyjdzie odpowiedź.
Jeśli strona rozsyłała spam, sprawdź też, czy domena i adres serwera nie trafiły na czarne listy poczty, i poproś hosting o pomoc w ich usunięciu. Zarejestruj stronę w Bing Webmaster Tools, bo Bing prowadzi własne ostrzeżenia.
Dlaczego wirus wraca po usunięciu
Powrót infekcji po kilku dniach to najczęstszy scenariusz po samodzielnym czyszczeniu. Przyczyny zwykle są trzy:
- Został backdoor. Usunięto przekierowanie, ale nie plik, przez który atakujący wgrywa nowe. Jeden zapomniany plik w
uploads, wpis w.user.inialbo zadanie cron wystarczy, żeby za tydzień wszystko wróciło. - Nie zamknięto luki. Ta sama nieaktualna wtyczka, ta sama wersja „nulled”, to samo hasło FTP zapisane w programie na zainfekowanym komputerze.
- Infekcja siedzi obok. Na hostingu współdzielonym jedno konto obsługuje często kilka stron: starą wersję strony, porzucony sklep testowy, stronę znajomego. Zainfekowana strona obok zaraża czystą. Czyścisz wszystkie strony na koncie albo przenosisz czystą na osobne konto.
Google w poradniku o ataku z japońskimi słowami kluczowymi przytacza badanie, według którego 20% zhakowanych witryn jest atakowanych ponownie w ciągu jednego dnia. Dlatego zamknięcie luki i zmiana haseł są częścią czyszczenia, a nie dodatkiem.
Ile kosztuje usunięcie wirusa z WordPressa
Na cenę wpływa skala, a nie samo słowo „wirus”. Czynniki, które ją podnoszą:
- liczba stron na tym samym koncie hostingu (każda wymaga sprawdzenia);
- spam w bazie danych: setki lub tysiące wpisów do usunięcia i adresy do wyrzucenia z indeksu Google;
- ostrzeżenie Google lub zablokowane konto, czyli dodatkowa korespondencja i weryfikacja;
- sklep z danymi klientów, w którym liczy się każda godzina i dochodzi ocena obowiązków RODO;
- wtyczki „nulled”, które trzeba zastąpić legalnymi licencjami.
U nas usunięcie malware kosztuje od 790 zł netto i obejmuje czyszczenie plików i bazy, zamknięcie luki, zgłoszenie do Google o ponowne sprawdzenie oraz 30 dni gwarancji. Szczegóły i cennik znajdziesz na stronie awaryjnej naprawy strony na WordPressie. Tanie usługi typu „skan i usunięcie wykrytych plików” bywają kuszące, ale jeśli nie obejmują szukania backdoorów i zamknięcia luki, płacisz dwa razy. O tym, jak zaplanować koszty strony na cały rok, piszemy w poradniku ile kosztuje utrzymanie strony internetowej.
Harmonogram działań: godzina, doba, tydzień
Ścieżka: każdy. Lista do wydrukowania albo przekazania osobie, która będzie czyścić stronę.
Pierwsza godzina
- Zrzuty ekranu objawów z godziną, kopia zainfekowanej strony i logi pobrane poza serwer.
- Nowe hasła do hostingu, FTP, poczty i kont administratorów, zmienione z czystego urządzenia.
- Nieznani administratorzy zanotowani, z odebraną rolą.
- Decyzja o przerwie technicznej (503) i kontakt z hostingiem.
- Ocena, czy atakujący mógł uzyskać dostęp do danych osobowych albo je zmienić lub usunąć. Termin 72 godzin biegnie od chwili stwierdzenia naruszenia.
Pierwsza doba
- Weryfikacja i podmiana rdzenia, wtyczek i motywów; usunięcie wersji „nulled” i nieużywanych dodatków.
- Przegląd
uploads,mu-plugins, drop-inów,.htaccess,.user.ini,wp-config.php, bazy danych i zadań cron. - Przegląd kont FTP, kluczy SSH, użytkowników bazy i przekierowań poczty.
- Wyczyszczenie cache wtyczki, serwera i CDN.
- Nowe klucze SALT, nowe hasło do bazy, druga zmiana wszystkich haseł, wymiana kluczy API i tokenów.
- Aktualizacje, wersja PHP, blokada PHP w
uploads, 2FA dla administratorów. - Ewentualne zgłoszenie do UODO i wpis w rejestrze naruszeń.
Pierwszy tydzień
- Ponowne testy curl i
site:po 2–3 dniach; porównanie listy plików z dniem czyszczenia. - Prośba o sprawdzenie w Search Console, gdy testy są czyste.
- Kopie zapasowe poza hostingiem, z co najmniej kilkudniową historią.
- Ustalenie, którędy weszła infekcja, i zapisanie tego w raporcie z incydentu.
Jak nie dopuścić do kolejnego włamania
Większość włamań na WordPressa nie wymaga od atakującego wyrafinowania. Wystarcza mu nieaktualna wtyczka ze znaną luką, hasło użyte w kilku serwisach albo dodatek z nieoficjalnego źródła. Według raportu Patchstack w 2025 roku 91% nowych luk w ekosystemie WordPressa dotyczyło wtyczek, 9% motywów, a w samym rdzeniu zgłoszono 6 luk. Dlatego profilaktyka jest nudna i regularna:
- aktualizacje co tydzień, najlepiej najpierw na kopii strony, żeby sama aktualizacja nie wywołała awarii;
- kopie zapasowe poza hostingiem, z historią na tyle długą, żeby sięgała sprzed włamania wykrytego po kilku tygodniach;
- monitoring zmian w plikach i dostępności strony, żeby o problemie dowiedzieć się przed klientami;
- osobne konto dla każdej osoby z dostępem, bez wspólnego loginu „admin”, z 2FA i usuwaniem kont osób, które już nie pracują przy stronie;
- jedna strona na jednym koncie hostingu albo przynajmniej usunięcie porzuconych instalacji.
Jeśli nie chcesz pilnować tego samodzielnie, możesz oddać stronę pod stałą opiekę techniczną: aktualizujemy na kopii, trzymamy kopie poza hostingiem i reagujemy na alerty monitoringu. Jeśli stronę przejąłeś od poprzedniego wykonawcy i nie wiesz, co w niej siedzi, zacznij od audytu przejęcia strony za 390 zł: sprawdzimy wtyczki, dostępy, kopie i ślady wcześniejszych infekcji.
Najczęstsze pytania
Zacznij od czterech bezpłatnych testów: wpisz domenę w Google Transparency Report (Bezpieczne przeglądanie), wyszukaj w Google site:twojadomena.pl i przejrzyj wyniki, otwórz w Search Console raport Problemy dotyczące bezpieczeństwa i sprawdź listę administratorów w kokpicie. Skanery online widzą tylko publiczne strony, więc czysty wynik nie wyklucza infekcji. Pewność daje dopiero porównanie plików z sumami kontrolnymi WordPressa i przegląd bazy danych.
To przekierowanie warunkowe, typowe dla zainfekowanego WordPressa. Złośliwy kod sprawdza, z jakiego urządzenia i skąd przychodzi gość, i przekierowuje tylko część ruchu, na przykład telefony albo wejścia z Google. Zalogowany administrator zwykle widzi normalną stronę, a często każdy gość jest przekierowany tylko raz, bo kod zapamiętuje jego ciasteczko albo adres IP. Testuj w trybie incognito na danych komórkowych albo poleceniem curl z innym user-agentem.
Zwykle nie. Wtyczka skanująca dobrze wyłapuje zmienione pliki i znane sygnatury, ale działa wewnątrz zainfekowanej instalacji, nie zamyka luki, przez którą weszła infekcja, i nie zawsze znajduje kod ukryty w bazie danych, zadaniach cron serwera, plikach .user.ini czy na innych stronach na tym samym koncie hostingu. Traktuj ją jako jedno z narzędzi diagnozy, a nie jako całe czyszczenie.
Zależy od hostingu i pakietu. Wiele firm hostingowych skanuje konta i przenosi wykryte pliki do kwarantanny albo blokuje konto, ale nie czyści bazy danych, nie szuka backdoorów i nie ustala, którędy weszła infekcja. Część hostingów oferuje płatne czyszczenie. Zawsze zapytaj o kopie sprzed ataku i o logi dostępu, bo to najcenniejsze, co hosting może Ci dać.
Tak, jeśli kopia na pewno pochodzi sprzed włamania i od razu po przywróceniu zamkniesz lukę: zaktualizujesz wtyczki, usuniesz dodatki nulled i zmienisz hasła. Włamanie bywa wcześniejsze od pierwszych objawów nawet o kilka tygodni, a kopie na hostingu często sięgają tylko kilku dni wstecz. Przywrócona strona ze starą, dziurawą wtyczką zwykle zostaje zainfekowana ponownie tą samą drogą.
Może. Hosting, który wykryje malware, potrafi przenieść zainfekowane pliki do kwarantanny albo zawiesić całe konto, a atakujący czasem kasuje treści, szyfruje pliki lub podmienia bazę. Kopie robione przez hosting bywają nadpisywane już zainfekowaną wersją. Dlatego od razu zrób kopię zainfekowanej strony do analizy i trzymaj regularne kopie poza hostingiem, z historią sięgającą kilku tygodni.
Zależy od skali infekcji: ile stron jest na koncie hostingu, czy spam trafił do bazy, czy Google oznaczył witrynę i czy to sklep z danymi klientów. Usunięcie malware zaczyna się u nas od 790 zł netto, a w cenie jest zamknięcie luki i 30 dni gwarancji. Uważaj na oferty samego skanu: bez szukania backdoorów infekcja zwykle wraca.
Jeśli atakujący mógł uzyskać dostęp do danych osobowych, zmienić je lub usunąć, na przykład kont klientów sklepu, zamówień albo wiadomości z formularzy zapisanych w bazie, to jest to naruszenie ochrony danych. Masz 72 godziny od jego stwierdzenia na zgłoszenie do Prezesa UODO, chyba że ryzyko dla osób jest mało prawdopodobne. Każde naruszenie trzeba też opisać w wewnętrznym rejestrze. W razie wątpliwości skonsultuj się z prawnikiem lub inspektorem ochrony danych.
Według Google sprawdzenie witryny po zgłoszeniu w Search Console trwa zwykle od kilku dni do kilku tygodni. Prośbę wysyłasz dopiero wtedy, gdy strona jest naprawdę czysta, bo przedwczesne zgłoszenie wydłuża kolejną weryfikację, a przy powtarzających się problemach Google może oznaczyć witrynę jako wielokrotnie naruszającą zasady. Do czasu decyzji nie wysyłaj kolejnych próśb.