POROZMAWIAJMY O PROJEKCIE

Z dziennika administratora stron, czyli 6 grzechów, które skończyły się awarią

Awaria strony rzadko wygląda jak awaria. Przez ostatnie sześć tygodni gasiliśmy sześć takich sytuacji i w czterech strona do końca zgłaszała, że wszystko jest w porządku. Za każdym razem to my informowaliśmy właściciela, nie odwrotnie.

Autor: Marcin Osak

Z artykułu dowiesz się

  • Grzech 1
    Monitoring, który patrzy tylko na kod odpowiedzi
  • Grzech 2
    Klucze uwierzytelniające z dnia instalacji
  • Grzech 3
    Brak dziennika zdarzeń
  • Grzech 4
    Kopia, której nikt nigdy nie odtwarzał
  • Grzech 5
    Kluczowe zadania zlecone automatowi
  • Grzech 6
    Migracja strony z wtyczką kopii wciąż wpiętą do starego serwera
  • Co z tego wynika?
  • Sześć rzeczy do sprawdzenia na własnej stronie
BEZPŁATNY AUDYT
Czy Twoja strona 
jest dobrze zabezpieczona?
Darmowy test online

Dla firmy wygląda to zwykle tak samo. Klient wchodzi na stronę i widzi biały ekran albo komunikat, że strony nie ma. Zapytania z formularza przestają przychodzić, a Google przez ten czas widzi pustą treść. Nic nie miga na czerwono, bo serwer grzecznie odpowiada, że strona żyje.

Programy, które pilnują stron, pytają najczęściej tylko o to jedno, czy serwer odpowiada. Nie sprawdzają, czy w odpowiedzi cokolwiek jest. To trochę jak sprawdzanie, czy ktoś odbiera telefon, zamiast pytać, czy w domu nie ma pożaru.

Od końca czerwca do początku sierpnia 2026 gasiliśmy awarie na sześciu witrynach opartych o WordPressa. Żadna nie zaczęła się od komunikatu o błędzie. W czterech z nich serwer przez cały czas odpowiadał kodem 200, czyli sygnałem, że wszystko jest w porządku. W dwóch pozostałych błąd było widać od razu, tyle że dopiero po wejściu na podstronę.

Grzech 1
Monitoring, który patrzy tylko na kod odpowiedzi

Strażnik z latarnią oświetla mur przy bramie, za którą jest otchłań, czyli monitoring strony widzący tylko kod HTTP 200

Właściciel zobaczył pustą, białą stronę bez żadnego komunikatu. W drugim przypadku stronę bez grafiki i formatowania, tak jakby ktoś zdjął z niej całą warstwę wizualną.

Między 24 a 25 lipca witryna producenta z branży technicznej zaczęła zwracać HTTP 200 z zerową treścią. Biały ekran, bez błędu 500. Złośliwe oprogramowanie podmieniło index.php, skasowało wp-login.php, a .htaccess kierował cały ruch do programu ładującego, który bez kontaktu ze swoim serwerem sterującym kończył pracę i nie wypisywał niczego. Każdy monitoring liczący kody odpowiedzi widział zdrową stronę.

Druga historia z tego samego lata: 13 lipca o 10:23 skompilowane arkusze stylów motywu zostały obcięte do 0 bajtów. style.min.css miał wcześniej 212 883 bajty. Serwer nadal odpowiadał 200 i uczciwie wysyłał pusty plik. Awarię zauważyliśmy dopiero 29 lipca, bo przez dwa tygodnie Cloudflare serwował poprawną, starą wersję arkusza ze swojego cache.

Co robić? Monitoring ma porównywać rozmiar odpowiedzi i zrzut ekranu strony, nie sam kod HTTP. Przy podejrzeniu infekcji sprawdzać listing plików przez FTP, bo brak wp-login.php na liście widać od razu, a w odpowiedziach HTTP nie widać go wcale.

Grzech 2
Klucze uwierzytelniające z dnia instalacji

Postać przenika przez zamknięte drzwi, a klucze wiszą nietknięte obok, czyli włamanie na konto przez domyślne salty WordPressa

Właściciel nie zobaczył niczego. Strona działała normalnie, tylko jego własne konto w panelu nazywało się już inaczej, a obok pojawiło się drugie konto administratora, którego nikt nie zakładał.

W witrynie pewnej firmy usługowej wp-config.php miał domyślne salty od 2019 roku. Salty to osiem losowych ciągów, którymi WordPress podpisuje ciasteczka sesji. Gdy są domyślne, ktoś znający nazwę użytkownika podrabia ciasteczko zalogowanego administratora bez znajomości hasła.

Efektem jest to, że login konta właściciela został podmieniony na AnonymousFox, czyli sygnaturę znanego zestawu narzędzi włamywacza, i doszło drugie konto administratora z zerową liczbą wpisów. Powłok webowych na serwerze nie było, baza była czysta. Włamanie odbyło się na poziomie kont, nie plików, więc żaden skaner plików by go nie pokazał.

Co robić? Zregenerować wszystkie osiem saltów (podrobione ciasteczka przestają działać w tej samej sekundzie), zrotować hasła bazy i FTP, przejrzeć listę administratorów. Konto administratora z zerową liczbą wpisów i adresem w dziwnej domenie to najtańszy sygnał do sprawdzenia.

Grzech 3
Brak dziennika zdarzeń

Kronikarz pisze w pustej księdze, a karty unosi wiatr, czyli brak dziennika zdarzeń w panelu WordPressa

Wczoraj, czyli 3 sierpnia, nasz klient dostał powiadomienie o zmianie hasła WordPressa, której sam nie wykonał. Sprawdziliśmy witrynę z zewnątrz: 166 adresów z obu map witryny pobranych jako Googlebot, zero obcych domen, zero fraz spamowych, brak cloakingu, REST API poprawnie zamknięte kodem 401, sondowanie typowych nazw tylnych furtek w katalogu głównym i w uploads dało same 404.

To dowodzi, że front jest czysty. Nie dowodzi, że nikt się nie zalogował. Odpowiedź na pytanie „kto i z jakiego adresu IP zmienił hasło” leży w dzienniku zdarzeń wewnątrz panelu, a taka wtyczka pomaga tylko wtedy, gdy działała przed zdarzeniem.

Co robić? Wtyczka dziennika zdarzeń typu Simple History zainstalowana w dniu oddania witryny, a nie w dniu awarii. Do tego komplet dostępów (panel, FTP, hosting) trzymany w jednym miejscu, bo bez nich diagnoza kończy się na tym, co widać z internetu. Co ciekawe, mieliśmy doświadczenia z firmami, które wykonywały optymalizację stron klientów i kasowały tę wtyczkę, aby rzekomo chronić swoje „bezcenne” know-how. W praktyce działały na niekorzyść swoich klientów i utrudniały lokalizację źródła i drogi infekcji.

Grzech 4
Kopia, której nikt nigdy nie odtwarzał

Rzędy zapieczętowanych skrzyń w krypcie, jedna otwarta i pusta w środku, czyli kopia zapasowa, której nikt nie odtwarzał

Strona główna wyglądała, jakby ktoś zdjął z niej połowę zawartości. Część sekcji po prostu zniknęła z widoku.

Po wyzerowaniu arkuszy sięgnęliśmy po kopie restic. Snapshot z 13 lipca, godzina 04:31, miał komplet plików CSS. Pliku dist/js/bundle.min.js nie miał żaden snapshot, bo katalog był pusty we wszystkich kopiach. Ten plik odpowiadał za zdejmowanie klasy lazyBg z elementów strony, więc bez niego znikły ikony społecznościowe, logo w stopce i dwanaście sekcji strony głównej, które zostały z przezroczystością zero. Oryginał, 16 860 bajtów, odnalazł się w kopii witryny sprzed migracji, leżącej na starym hostingu.

Co robić? Raz na kwartał odtworzyć kopię do katalogu testowego i policzyć pliki. Kopia, której nikt nie odtwarzał, jest hipotezą. Osobna sprawa: po podmianie pliku statycznego trzeba podnieść numer wersji w kodzie motywu, bo te pliki lecą z nagłówkiem max-age ustawionym na 10 lat i przeglądarka stałego czytelnika nawet nie zapyta serwera o nową treść.

Grzech 5
Kluczowe zadania zlecone automatowi

Mechaniczny automat tnie nożycami zwój, człowiek stoi obok bezczynnie, czyli chatbot hostingu okrawający plik .htaccess

Strona główna działała, a wszystkie pozostałe podstrony pokazywały komunikat, że strony nie ma. Także te, na które prowadziły reklamy i wyniki w Google.

Chatbot dostępny w panelu popularnego hostingu dostał zadanie utwardzenia .htaccess. Dokleił reguły blokujące xmlrpc, wp-cron i admin-ajax, a przy okazji uciął plik zaraz za linią # BEGIN WordPress, kasując cały blok przepisywania adresów. Skutek, strona główna działa, bo trafia w index.php, a każda podstrona zwraca 404. Zdarzyło się dwa razy, 23 czerwca na jednej domenie i 29 czerwca na partii pięciu, z czego trzy zostały ucięte. Autoryzowana była wyłącznie blokada readme.txt.

Co robić? Po każdej zmianie .htaccess otworzyć realną podstronę wziętą z mapy witryny, nie stronę główną. Zachować kopię pliku sprzed edycji, bo rollback trwa wtedy minutę. Blokowanie wp-cron.php na hostingu współdzielonym warto pominąć, bo cicho wyłącza zadania cykliczne WordPressa.

Grzech 6
Migracja strony z wtyczką kopii wciąż wpiętą do starego serwera

Łódź z ładunkiem odpływa, ale lina wciąż trzyma ją przy starym brzegu, czyli migracja z wtyczką kopii wpiętą do starego serwera

Zaraz po przeprowadzce na nowy serwer strona przestała się otwierać, a zdjęcia z całej witryny zniknęły.

15 lipca, po przełączeniu DNS na nowy hosting, witryna zaczęła zwracać błąd połączenia z bazą, a chwilę później tryb konserwacji. Wtyczka kopii zapasowych na zmigrowanej witrynie nadal była wpięta do konta, którego kopia pochodziła ze starego serwera. Po zmianie DNS serwis uznał, że domena wskazuje teraz nowy serwer, i uruchomił automatyczne przywracanie. Nadpisało wp-config.php danymi bazy, która na nowym hoście nie istnieje, i skasowało wp-content/uploads. Nikt niczego nie kliknął.

Ta sama migracja przyniosła drugą pułapkę. Reguły WebP Express zapisane w .htaccess w katalogach uploads i themes mają zahardkodowane ścieżki starego hostingu. Obrazki fizycznie leżą na serwerze, curl pobiera je jako poprawny JPEG, ale przeglądarka wysyłająca nagłówek Accept: image/webp dostaje komunikat o ścieżce poza basedir.

Co robić? Przed przełączeniem DNS wyłączyć wtyczkę kopii zapasowych albo odpiąć witrynę w panelu usługi. Nie przenosić plików .htaccess wygenerowanych przez WebP Express. Test diagnostyczny to jedno polecenie: curl -H „Accept: image/webp” , a odpowiedź typu text/html wskazuje winowajcę.

Co z tego wynika?

W żadnym z tych 6 przypadków naprawa nie trwała dłużej niż 1 dzień roboczy, bo nasi klienci powierzają nam obsługę swoich stron i nam ufają

Mamy odpowiednio zabezpieczone i zdywersyfikowane dane dostępowe i sprawdzony zestaw wtyczek, z którymi pracujemy. Wielu z nich ma również subskrypcje kompleksowej opieki technicznej nad WordPressem. Mamy narzędzia i możliwości oraz „mandat” do tego, aby samemu gasić pożary, zanim zrobią nieodwracalne zniszczenia.

Kosztowne z kolei było wykrycie incydentów, bo awarie tliły się niezauważone od kilku dni do 2 tygodni działania witryny. Wszystkie 6 błędów to rzeczy, które robi się raz i sprawdza cyklicznie, a nie umiejętności wymagające programisty pod telefonem.

Dlatego to my zaalarmowaliśmy klientów, że coś jest nie tak, a nie odwrotnie i mieliśmy narzędzia do tego, aby je wyeliminować.

Sześć rzeczy do sprawdzenia na własnej stronie

Jeśli nie masz kogoś, kto pilnuje tego za ciebie, to jest minimum do przejścia raz.

  1. Sprawdź, czy ktokolwiek pilnuje Twojej strony inaczej niż samym pytaniem, czy serwer odpowiada. Dobre czuwanie porównuje wygląd i rozmiar strony, nie sam sygnał życia.
  2. Zapytaj, kiedy ostatnio zmieniano klucze zabezpieczające WordPressa. Jeśli odpowiedź brzmi „nigdy”, robi się to w kwadrans.
  3. Otwórz listę kont administratorów w panelu. Każde konto, którego nie rozpoznajesz, wymaga wyjaśnienia.
  4. Poproś raz o odtworzenie kopii zapasowej na testowej wersji strony. Kopia, której nikt nigdy nie odtwarzał, jest tylko obietnicą.
  5. Sprawdź, czy masz w jednym miejscu wszystkie dostępy, do panelu, hostingu, domeny i poczty. Bez nich każda naprawa zaczyna się od szukania.
  6. Po każdej większej zmianie na stronie otwórz dowolną podstronę, nie tylko stronę główną. Większość awarii z tego artykułu widać właśnie tam.
Marcin Osak

Autor: Marcin Osak

Założyciel agencji interaktywnej Avangardo, którą prowadzi od 2008 roku. Tworzy strony i sklepy internetowe. Od lat pasjonuje się SEO, a od kilku lat także AI i optymalizacją stron pod wyszukiwanie generatywne (GEO). Ma za sobą ponad 1000 zrealizowanych projektów dla firm z całej Polski i Europy.