Pierwsza publikacja: 21 października 2026. Ostatnia aktualizacja: 22 października 2026, 13:00.
21 października zespół PHP wydał awaryjne poprawki dla dwóch krytycznych podatności: CVE-2026-109618 i CVE-2026-109619. Obie mają ocenę 9.2 w skali CVSS v4.0 i obie pozwalają na zdalne wykonanie kodu bez logowania. Szczegóły wyciekły przed planowaną publikacją, dlatego wydanie przyspieszono, a ryzyko szybkich ataków jest realne. Dlaczego ta luka wyłączyła strony urzędów i część Wikipedii, wyjaśniamy bez technicznego żargonu we wpisie PHP2Shell: co się stało i co to znaczy dla Twojej strony.
Na VPS-ie aktualizujesz pakiety i po sprawie. Na hostingu współdzielonym PHP aktualizuje dostawca i dopóki tego nie zrobi, Twoja strona działa na podatnej wersji. Hostingodawcy wdrażają teraz poprawki na tysiącach serwerów naraz. Ten wpis jest o tym, co możesz zrobić sam w międzyczasie, bez dostępu do konfiguracji serwera.
W skrócie
- Wersje z poprawką: 8.5.12, 8.4.27, 8.3.36, 8.2.35. Wszystko starsze w tych gałęziach jest podatne.
- Zagrożone: każda instalacja PHP obsługująca ruch WWW: mod_php, PHP-FPM, php-cgi, LiteSpeed, FrankenPHP. Najgorzej jest z mod_php.
- Atak działa, zanim ruszy WordPress. Dlatego wtyczki bezpieczeństwa, tryb serwisowy z wtyczki i ukrywanie błędów nic tu nie dają.
- Jedyne pełne rozwiązanie to aktualizacja PHP. Poniższe kroki tylko zmniejszają ryzyko.
1. Sprawdź, czy Twój PHP ma już łatkę
Nie musisz nikogo pytać. Wgraj do katalogu strony plik o losowej nazwie i otwórz go w przeglądarce:
<?php phpinfo();
Interesują Cię trzy linie z samej góry:
- PHP Version: porównaj z tabelą poniżej.
- Build Date: data kompilacji. Jeśli jest sprzed 21 października 2026, masz binarkę sprzed poprawki, nawet jeśli numer wygląda świeżo.
- Server API: od tego zależy, które z dalszych kroków w ogóle zadziałają (punkt 2).
| Twoja gałąź | Bezpieczna od wersji | Uwagi |
|---|---|---|
| 8.5 | 8.5.12 | Dodatkowo ustaw fatal_error_backtraces=0 (punkt 4) |
| 8.4 | 8.4.27 | |
| 8.3 | 8.3.36 | |
| 8.2 | 8.2.35 | Koniec wsparcia 31 grudnia 2026, planuj przesiadkę |
| 8.1 i starsze | brak oficjalnego wydania | Łatka tylko jako backport od dostawcy. Jeśli panel pozwala, przejdź na wspieraną gałąź, gdy ta zostanie zaktualizowana |
Numer wersji niższy niż w tabeli nie zawsze oznacza brak łatki. Część hostingodawców wgrała poprawki do wersji, których już używa (tzw. backport), także do starych gałęzi 5.x i 7.x. Wtedy phpinfo pokaże niższy numer, a PHP i tak jest załatane. W takim przypadku rozstrzyga komunikat Twojego hostingu oraz data kompilacji: 21 października 2026 lub późniejsza.
Masz SSH? php -v pokaże wersję, ale tylko tej binarki, która działa w konsoli. Strona może korzystać z innej, więc rozstrzyga phpinfo otwarte przez przeglądarkę.
2. Server API decyduje, co możesz zmienić
| Server API w phpinfo | Co to znaczy | Czy php_flag w .htaccess działa |
|---|---|---|
| Apache 2.0 Handler | mod_php, najwyższe ryzyko | Tak |
| LiteSpeed V… | LSAPI | Zwykle tak, sprawdź efekt w phpinfo |
| FPM/FastCGI, CGI/FastCGI | PHP-FPM lub CGI | Nie. Taki wpis da błąd 500. Zostaje panel hostingu |
Ważne: zespół PHP wprost zaznacza, że zmiany przez ini_set() (np. w wp-config.php) ani przez plik .user.ini przy PHP-FPM nie chronią. Ustawienie musi zadziałać, zanim PHP zacznie czytać żądanie. Czyli: panel hostingu (sekcja ustawień PHP dla domeny) albo, przy mod_php i LiteSpeed, .htaccess.
3. Czy wyłączyć stronę?
Rozważ to poważnie, jeśli:
- Server API to Apache 2.0 Handler, bo dla mod_php pokazano działający exploit,
- prowadzisz sklep albo serwis z kontami klientów i danymi osobowymi,
- nie możesz zmienić żadnego z ustawień z punktu 4.
Tylko jedno: wtyczka „tryb serwisowy” nie wystarczy. Ona też jest kodem PHP, więc żądanie atakującego i tak dociera do interpretera. Stronę trzeba zamknąć na poziomie serwera WWW, zanim żądanie trafi do PHP. Na Apache i LiteSpeed robi to .htaccess.
Utwórz zwykły plik przerwa.html (czysty HTML, żadnego PHP) z krótką informacją o przerwie technicznej. Potem dopisz na samej górze pliku .htaccess, przed blokiem WordPressa:
# PRZERWA: wszyscy dostaja statyczna strone 503, poza Twoim IP
RewriteEngine On
RewriteCond %{REMOTE_ADDR} !^203\.0\.113\.10$
RewriteCond %{REQUEST_URI} !^/przerwa\.html$
RewriteRule ^ - [R=503,L]
ErrorDocument 503 /przerwa.html
<IfModule mod_headers.c>
Header always set Retry-After "7200"
</IfModule>
# KONIEC PRZERWY
Koniecznie przetestuj blokadę z dwóch miejsc. Wyjątek dla Twojego IP działa tylko wtedy, gdy serwer widzi prawdziwy adres odwiedzającego. Przy Cloudflare albo gdy przed Apache stoi proxy (nginx, Varnish) bez przekazywania adresu klienta, serwer widzi adres proxy. Wtedy reguła blokuje wszystkich, łącznie z Tobą. Dlatego:
- Telefon na danych komórkowych, z wyłączonym Wi-Fi: musisz zobaczyć stronę przerwy. Jeśli widzisz normalną stronę, blokada nie działa. Usuń wpisy i zamknij stronę z panelu hostingu.
- Twój komputer: powinieneś widzieć normalną stronę. Jeśli też widzisz przerwę, serwer nie zna Twojego IP. Blokada działa, tylko bez wyjątku. Usuń linię z adresem IP albo zostaw stronę zamkniętą dla wszystkich.
- Jeśli łączysz się przez IPv6, Twój adres wygląda inaczej niż IPv4. Sprawdź go w dowolnym serwisie „jaki mam IP”.
- Nie zamieniaj
REMOTE_ADDRna nagłówekX-Forwarded-For. Ten nagłówek atakujący może podać sam, więc otworzyłbyś mu furtkę. - Hostingi oparte wyłącznie na nginx ignorują .htaccess. Tam stronę zamkniesz tylko z panelu.
4. Ustawienia PHP, które zmniejszają ryzyko
Jeśli nie wyłączasz strony, to jest minimum. Pochodzi wprost z komunikatu bezpieczeństwa PHP. Najlepiej wprowadzić je w panelu hostingu, w ustawieniach PHP dla domeny:
; blokuje potwierdzone sciezki ataku przez sesje (CVE-2026-109619)
session.upload_progress.enabled = 0
; tylko PHP 8.5: blokuje sciezke przez backtrace bledow krytycznych
fatal_error_backtraces = 0
; maly limit rozmiaru zadania (CVE-2026-109618)
; strona bez wysylania plikow: 8M, z wysylaniem: 32M
post_max_size = 8M
upload_max_filesize = 7M
upload_max_filesize zawsze ustaw niżej niż post_max_size.Przy Apache 2.0 Handler albo LiteSpeed te same wartości możesz wpisać do .htaccess. Przy FPM nie rób tego, bo strona odpowie błędem 500:
php_flag session.upload_progress.enabled off
php_value post_max_size 8M
php_value upload_max_filesize 7M
# tylko PHP 8.5:
php_flag fatal_error_backtraces off
Czego nie ustawiać: memory_limit=-1. Komunikat PHP wymienia też to ustawienie, ale jest ono przeznaczone dla serwerów, na których administrator kontroluje limity na poziomie systemu. Na hostingu współdzielonym go nie zmieniaj. Wtedy każde żądanie atakującego może zużywać pamięć bez ograniczeń, aż proces trafi na twardy limit Twojego konta. Skutkiem mogą być przestoje wszystkich stron na koncie, a przy powtarzającym się przeciążeniu także ograniczenie konta przez hosting. Zostaw memory_limit bez zmian.
Sprawdź efekt. Po każdej zmianie otwórz ponownie phpinfo i znajdź session.upload_progress.enabled oraz post_max_size. Kolumna Local Value musi pokazywać nowe wartości. Jeśli nie pokazuje, zmiana nie działa.
5. Limit rozmiaru żądania na poziomie serwera
Zespół PHP zaleca też ograniczenie rozmiaru żądania przed PHP. Na Apache możesz to zrobić w .htaccess:
# 8 MB w bajtach; przy wysylaniu plikow ustaw 33554432 (32 MB)
LimitRequestBody 8388608
6. Posprzątaj błędy, które atakujący może wywołać
Druga podatność wykorzystuje stan, który zostaje po błędach krytycznych i przekroczeniu czasu wykonania. Zespół PHP zaleca usuwanie takich błędów, ale to tylko zawęża liczbę dróg ataku. Atakujący może sam wywołać błąd odpowiednio spreparowanym żądaniem, więc czysty log nie znaczy, że strona jest bezpieczna. Ukrycie błędów (display_errors=Off, @) nie pomaga wcale.
Jeśli masz SSH, przejrzyj log błędów:
# przestarzale lub bledne ustawienia PHP
grep -iE "deprecated|PHP Startup" error_log | tail -n 20
# bledy krytyczne i przekroczenia limitow
grep -E "Fatal error|Allowed memory size|Maximum execution time" error_log | tail -n 20
Szczególnie zwróć uwagę na stare wpisy php_value w .htaccess i w plikach .user.ini, które ustawiają nieistniejące lub przestarzałe dyrektywy. Generują ostrzeżenia przy każdym żądaniu, a dokładnie takie ostrzeżenia komunikat PHP wymienia jako ścieżkę ataku. Usuń je. Jeśli w logu powtarza się błąd krytyczny konkretnej wtyczki, wyłącz ją do czasu aktualizacji PHP.
7. Zrób kopię teraz, sprawdź pliki później
Zrób pełną kopię plików i bazy teraz, zanim cokolwiek się wydarzy. To będzie Twój czysty punkt odniesienia. Po aktualizacji PHP warto sprawdzić, czy nikt nie zdążył się zadomowić:
# w katalogu uploads nie powinno byc zadnego pliku PHP
find wp-content/uploads -name "*.php"
# pliki PHP zmienione od 19 pazdziernika
find . -name "*.php" -newermt "2026-10-19" -not -path "./wp-content/cache/*"
# konta administratorow i daty ich utworzenia
wp user list --role=administrator --fields=ID,user_login,user_registered
8. Jeśli prowadzisz sklep
Właściciele sklepów na WooCommerce dostają dziś ostrzeżenia od operatorów płatności i zespołów CSIRT. To właśnie ta sprawa. Sklep to najbardziej oczywisty cel, bo przetwarza dane klientów, więc tu próg do wyłączenia strony na kilka godzin jest niższy.
Pamiętaj, że przerwa z punktu 3 blokuje też powiadomienia od bramki płatności. Po otwarciu sklepu przejrzyj zamówienia z czasu przerwy i sprawdź, czy statusy płatności się zgadzają.
9. Gdy PHP zostanie zaktualizowany
- Sprawdź w phpinfo wersję i Build Date z 21 października 2026 lub późniejszą.
- Usuń blok przerwy z .htaccess.
- Jeśli obniżałeś limity wysyłania plików, przywróć potrzebne wartości.
session.upload_progress.enabled=0możesz zostawić na stałe. WordPress z tego nie korzysta.- Wykonaj kontrolę z punktu 7.
- Usuń plik z phpinfo.
Czego nie robić
- Nie licz na wtyczki bezpieczeństwa ani zapory działające wewnątrz WordPressa. Atak odpala się, zanim one się uruchomią.
- Nie wstawiaj
ini_set()do wp-config.php w nadziei, że zablokuje atak. Działa za późno. - Nie uznawaj sprawy za zamkniętą po samych ustawieniach z punktu 4. Zespół PHP pisze wprost, że jedynym bezpiecznym wyjściem jest aktualizacja.

