Aktualizacja bezpieczeństwa PHP 2026: przewodnik po naprawie PHP2Shell (CVSS 9.2)
21 października 2026 r. PHP wydał wersje 8.5.12, 8.4.27, 8.3.36 i 8.2.35, zamykając dwie podatności typu RCE niewymagające uwierzytelnienia. Jeśli Twój serwer, serwer klienta albo wspólny hosting Twojej agencji działa na PHP, to zadanie na dziś, a nie punkt harmonogramu.
Samo ujawnienie było nietypowe. 20 października zespół bezpieczeństwa PHP opublikował zapowiedź, wyznaczył wydanie na 21 października na godzinę 14:00 UTC i zastrzegł sobie prawo wcześniejszego opublikowania. Identyfikatory CVE wyciekły dzień przed ujawnieniem razem z przesadzonymi doniesieniami o dotkliwości i objętych wersjach. Dostawcy dystrybucji już wcześniej otrzymali łatki, a krajowe zespoły CERT zaczęły publikować zalecenia, zanim kod trafił do publicznej sieci. Innymi słowy: po wydaniu poprawek nikt nie miał wiarygodnej wymówki, żeby zwlekać.
Dwie podatności, jedno wydanie awaryjne
Żaden z tych błędów nie jest błędem logiki aplikacji. Oba dotyczą sposobu, w jaki PHP przygotowuje żądanie i je zamyka, dlatego żadna aktualizacja frameworka, wtyczki ani reguła WAF nie zastąpi aktualizacji interpretera.
CVE-2026-109618 — RCE przez uszkodzenie przy braku pamięci. Gdy PHP wyczerpie pamięć, przerywa żądanie zamiast kontynuować. Komunikat opisuje ścieżkę, w której takie przerwanie zatrzymuje PHP, gdy wewnętrzne dane żądania są zainicjowane tylko częściowo, więc późniejszy krok sprzątania żądania traktuje nieprawidłowe dane jako prawidłowe. Atakujący, który potrafi doprowadzić użycie pamięci do limitu, może w ten sposób sterować tym, co stanie się dalej. To ta podatność sprawia, że zalecenia łagodzące są tak sprzeczne z intuicją: producent prosi administratorów, żeby nie pozwalać PHP wpadać we własny limit pamięci, a nie żeby go zaostrzać.
CVE-2026-109619 — RCE przez przestarzały stan globalny. Stan wewnętrzny należący do jednego żądania może przetrwać po zwolnieniu pamięci, na której leżał. Kolejne żądanie obsługiwane przez ten sam proces roboczy może użyć tego przestarzałego stanu, zanim normalna inicjalizacja go zresetuje. W przypadku długo żyjącego workera — a dokładnie takim jest PHP-FPM, mod_php i LiteSpeed — ponowne użycie pamięci to normalny, stały stan, dlatego nie jest to przypadek brzegowy dla egzotycznych konfiguracji.
| Identyfikator | Co to jest | Dotkliwość | Naprawione w |
|---|---|---|---|
| CVE-2026-109618 GHSA-w8hw-w9fx-j79w |
Obsługa braku pamięci przerywa PHP przy częściowo zainicjowanych danych żądania; sprzątanie traktuje wtedy nieprawidłowe dane jako prawidłowe | CVSS v4.0 9.2 | 8.5.12 · 8.4.27 · 8.3.36 · 8.2.35 |
| CVE-2026-109619 GHSA-6wmf-4rv5-p3rp |
Stan należący do żądania przetrwa po zwolnieniu pamięci; kolejne żądanie na tym samym workerze korzysta z niego przed ponowną inicjalizacją | CVSS v4.0 9.2 | 8.5.12 · 8.4.27 · 8.3.36 · 8.2.35 |
Nazwa PHP2Shell nie jest oficjalnym oznaczeniem projektu PHP; weszła do użycia od badaczy i firm bezpieczeństwa i się przyjęła, więc spotkasz ją w wynikach skanerów, biuletynach hostingowych i zaleceniach CERT, które odnoszą się dokładnie do tych dwóch CVE.
Kto jest naprawdę zagrożony
Komunikat jest szczery: zagrożone są wszystkie instalacje PHP, które obsługują żądania WWW. Obejmuje to PHP-FPM za nginxem lub Apachem, Apache z mod_php, php-cgi, LiteSpeed i FrankenPHP. Różnica między nimi sprowadza się do tego, ile pracy musi wykonać atakujący.
| Konfiguracja | Ryzyko | Dlaczego |
|---|---|---|
| Apache z mod_php | Najwyższe | Komunikat opisuje zademonstrowany exploit, w którym nieuwierzytelnione żądanie uruchamia atak, zanim wykona się jakikolwiek kod aplikacji |
| PHP-FPM (nginx, proxy Apache) | Wysokie | Długotrwałe workery ponownie używają stanu żądania; worker zwykle działa jako ten sam użytkownik co serwis |
| LiteSpeed, php-cgi, FrankenPHP | Wysokie | Wymienione w komunikacie jako objęte konfiguracje obsługujące żądania |
| Hosting zarządzany i współdzielony | Zróżnicowane — dopytaj | Zwykle łatane na poziomie platformy, ale nie widać tego; Twoim zadaniem jest uzyskanie na piśmie wbudowanej wersji i daty łatania |
| Zadania cron i skrypty CLI | Ryzyko niższe — i tak aktualizuj | Brak publicznej powierzchni żądań, ale korzystają z tego samego pliku binarnego i często przechowują poświadczenia |
Jeśli hostujesz WordPress, WooCommerce, Laravel, Magento, systemy ERP pokrewne Magento albo dowolny portal rezerwacyjny w PHP dla swojej firmy handlowej, wpisujesz się w pierwsze trzy wiersze, nawet gdy kod aplikacji jest bezbłędny. Szersze spojrzenie na to, kto w ogóle powinien zajmować się środowiskiem uruchomieniowym, znajdziesz w naszym przewodniku po outsourcingu IT w Turcji.
Sprawdź swoją wersję w dwie minuty
Pułapką jest tu arytmetyka wersji. Dystrybucje przez lata dostarczają PHP 8.3.6 albo 8.2.x i backportują poprawki bezpieczeństwa do tego samego widocznego numeru, więc php -v samo nie powie Ci, czy jesteś chroniony. Porównaj trzy rzeczy.
1. Widoczna wersja PHP i SAPI, która obsługuje ruch.
php -i | grep -E 'PHP Version|memory_limit|session.upload_progress.enabled|fatal_error_backtraces'
systemctl list-units --type=service --state=running | grep -Ei 'php|apache|nginx|litespeed'
2. Wersja pakietu dystrybucji, a nie wersja z projektu upstream. Na Debianie i Ubuntu uczciwą odpowiedzią jest changelog; w systemach RPM trzeba odpytać changelog pakietu.
zcat /usr/share/doc/php8.3-cli/changelog.Debian.gz | grep -iE 'CVE-2026-10961[89]'
apt-cache policy php8.3-fpm | head -4
# RPM-based hosts
rpm -q php && rpm -q --changelog php | grep -iE 'CVE-2026-10961[89]'
Jeśli changelog wymienia obie podatności CVE w zainstalowanej wersji, jesteś załatany, choć php -v nadal pokazuje 8.3.6. Taka jest różnica między prawdziwą odpowiedzią bezpieczeństwa a przesądem opartym na numerze wersji.
3. Czy uruchomiony proces wczytał ponownie załatany plik binarny. Aktualizacja pakietu, po której nie następuje restart, zostawia stary kod w pamięci. Porównaj czas startu usługi z czasem instalacji pakietu:
stat -c '%y %n' /usr/sbin/php-fpm8.3
W cPanel, Plesk, DirectAdmin czy na platformie zarządzanej odpowiednikiem jest selektor PHP oraz biuletyn bezpieczeństwa hosta: ustal wbudowaną wersję faktycznie przypisaną do Twojej witryny, a nie najnowszą reklamowaną w panelu. Jeśli host nie potrafi podać daty łatania, traktuj witrynę jako niezałatą. Nasze usługi infrastruktury cyfrowej obejmują ten audyt oraz samą aktualizację; możesz też po prostu skontaktować się z nami ze swoim stackiem, a powiemy, co byśmy sprawdzili.
Wersje z poprawkami i urwisko EOL
PHP wspiera gałąź przez dwa lata aktywnego rozwoju i dwa kolejne lata poprawek bezpieczeństwa. Ta polityka właśnie dała cztery równoczesne poprawki 21 października — i to ona zostawia starsze gałęzie same sobie.
| Gałąź | Wersja z poprawką | Status po tym komunikacie |
|---|---|---|
| PHP 8.5 | 8.5.12 | Aktywne wsparcie |
| PHP 8.4 | 8.4.27 | Aktywne wsparcie |
| PHP 8.3 | 8.3.36 | Faza wsparcia bezpieczeństwa |
| PHP 8.2 | 8.2.35 | Wsparcie bezpieczeństwa kończy się 31 grudnia 2026 — zaplanuj przeskok już teraz |
| PHP 8.1 i starsze | Brak wydania upstream | Tylko backporty dostawców; projekt PHP opublikował minimalne backporty źródłowe dla 7.4, 8.0 i 8.1 dla budujących ze źródeł |
Dwie praktyczne przestrogi z komunikatu. Po pierwsze: jeśli instalujesz PHP z repozytorium społeczności zamiast z dystrybucji, takie repozytorium może nie nadążać za oknem bezpieczeństwa — opiekunowie szeroko używanych pakietów Remi zaznaczyli, że nie zdążą z aktualizacjami tego samego dnia, więc bezpieczną drogą są pakiety Twojej dystrybucji albo budowa ze źródeł. Po drugie: jeśli jesteś na PHP 8.1 albo starszym, „czekamy na naszego hosta" to decyzja bezpieczeństwa podejmowana w imieniu Twoich klientów — udokumentuj ją albo ją zmień.
Załatanie produkcyjnego serwera bez incydentu
Aktualizacje bezpieczeństwa w obrębie tej samej wersji podrzędnej rzadko psują aplikację; psują ją nietestowane restarty. Poniższa kolejność to to, czego używamy na żywych platformach handlowych, i utrzymuje ona krótkie okno ryzyka bez stawiania na szali całej witryny.
- Najpierw snapshot. Snapshot hipervisora albo woluminu, którego odtworzenie faktycznie przetestowałeś, przywraca system w minuty i czyni decyzję o łatanie taną.
- Odtwórz wersję na stagingu. Ta sama gałąź, te same rozszerzenia, te same pliki konfiguracyjne PHP, kopia danych produkcyjnych. Przetestuj ścieżki koszyka, zapytania ofertowe i płatności, a nie tylko stronę główną.
- Aktualizuj zestaw pakietów jako całość. Wymieszanie zaktualizowanego CLI ze starym plikiem binarnym FPM to prosta droga do załatanego
php -vi niezałatanej ścieżki WWW:apt-get update && apt-get install --only-upgrade 'php8.3-*'albodnf update --security 'php*'na hostach RPM. - Zrestartuj proces obsługujący żądania, a potem sprawdź, czy na pewno się zrestartował.
systemctl restart php8.3-fpm(albo reload Apache / restart LiteSpeed), potem ponownie sprawdź czas startu usługi i jeszcze raz wykonaj zapytania o wersję i changelog. - Obserwuj log błędów przez godzinę. Komunikaty OOM, nowe sygnatury błędów krytycznych i nietypowe odsetki 5xx to sygnały, że poniższe ustawienia łagodzące mogą wymagać dostrojenia — a nie powody, by odkładać aktualizację.
- Zapisz dowody. Wersja pakietu, wiersz changeloga z obiema podatnościami CVE, znacznik czasu restartu. Klienci, audytorzy i przeglądy kontrolek w stylu ISO 27001 pytają o dokładnie to, a zapisanie zajmuje dziesięć sekund.
Tam, gdzie aktualizacja musi poczekać — zwalidowana integracja ERP, embargo kalendarza wydań, pętla akceptacji klienta — postaw tego samego dnia przed nią kontrolę kompensującą, zamiast zostawiać port otwarty i mieć nadzieję. Właśnie to zalecały w tej sytuacji biuletyny krajowych zespołów CERT: odizoluj aplikacje PHP dostępne z internetu od sieci publicznej, gdy natychmiastowe łatanie nie jest możliwe.
Tymczasowe łagodzenie: zawęź okno, nie zamykaj go
Komunikat PHP mówi wprost, że nie istnieje pełne łagodzenie i że aktualizacja to jedyny bezpieczny wybór. Traktuj poniższe środki jako osłonę na dni, nie tygodnie, zastosowaną na poziomie, którego kod aplikacji nie może nadpisać, a po wszystkim ze zrestartowanymi workerami.
Przeciwko CVE-2026-109618 (ścieżka braku pamięci)
- Pozwól PHP wyczerpać pamięć maszyny zamiast własnego limitu:
memory_limit = -1, najlepiej jakophp_admin_value memory_limit = -1, żeby kod aplikacji nie mógł przywrócić sufitu. - Utrzymuj małe treści żądań na poziomie interpretera: zalecenie komunikatu to około 8 MB, gdy nie ma uploadów, i około 32 MB, gdy są, przy
upload_max_filesizeponiżejpost_max_size. - Egzekwuj kosztowne limity na proxy, bo szkoda siedzi w rozkodowanym żądaniu, a nie w rozmiarze pakietu: łączny rozmiar rozkodowanego body, liczba pól wejściowych, liczba części multipart, liczba nagłówków, głębokość zagnieżdżenia — i obejmij też żądania przychodzące bez użytecznego
Content-Length. - Ogranicz promień rażenia limitem pamięci kontenera albo cgroupa dobranym tak, że zabity worker to zdarzenie dostępności, a nie zdarzenie całego hosta. Nie podstawiaj
RLIMIT_ASaniRLIMIT_DATA: te wyzwalają dokładnie ten błąd alokacji, który leży w podatnej ścieżce.
Przeciwko CVE-2026-109619 (ścieżka przestarzałego stanu)
- Wyłącz postęp uploadu sesji:
session.upload_progress.enabled = 0, ustawione w php.ini, puli FPM albo konfiguracji serwera — tam, gdzie zadziała przed parsowaniem żądania. Potem zrestartuj wszystkie workery, bo FPM współdzieli między żądaniami już zainicjowany stan modułów.ini_set()i.user.inidziałają za późno. - Na PHP 8.5 ustaw
fatal_error_backtraces = 0i zrestartuj. - Usuń ustawienia per żądanie, które są nieprawidłowe albo wycofane i dlatego emitują diagnostykę we wczesnej inicjalizacji. Wytłumienie komunikatu przez
error_reporting,display_errorsalbo@nie usuwa ścieżki kodu. - Poluj na osiągalne dla atakującego błędy krytyczne i długo działające przekroczenia czasu w handlerach uploadu i importu, kodzie wywołań zwrotnych i procedurach sprzątania — w tych samych miejscach mieszkają oba błędy.
CDN albo WAF przed originem nadal robi swoje: rate limiting, blokowanie anomalicznych kształtów żądań i wirtualne łatki redukują szum i spowalniają oportunistyczne skanowanie. Dla ukierunkowanego atakującego to zwalniacz, a nie kontrola, którą można podpisać jako remediację.
O co zapytać dziś dostawcę hostingu
Skrypty wsparcia odpowiadają na to pytanie formułą „zawsze mamy łatki". Zapytaj zamiast tego o dowody, które możesz odłożyć do akt:
- Wbudowaną wersję PHP przypisaną do naszego konta oraz to, czy to pakiet dystrybucji, czy build dostawcy.
- Datę, kiedy poprawki CVE-2026-109618 i CVE-2026-109619 dotarły do Twojej floty, wraz z wewnętrznym oznaczeniem wersji pakietu.
- Czy poprawka obejmuje SAPI obsługującą naszą witrynę (FPM, LiteSpeed, mod_php) oraz każdy węzeł stagingowy albo zapasowy, z którego moglibyśmy odtwarzać.
- Jeśli platforma nie jest jeszcze załatana: jaka kontrola kompensująca działa i do kiedy.
- Twoją stałą politykę dla gałęzi EOL — co stanie się z moją witryną 1 stycznia 2027, gdy skończy się wsparcie bezpieczeństwa PHP 8.2.
Dostawca, który odpowiada na te pięć pytań w jednym mailu, to dostawca, którego warto zatrzymać. Taki, który odbija się tekstem marketingowym, to już rozmowa o migracji; ta sama staranność obowiązuje w naszej pracy analizy luk ISO 27001, gdzie produktem jest dowód, a nie uspokojenie.
Czy należy założyć, że doszło do włamania?
Nie automatycznie — ale sprawdź, zamiast zgadywać, zwłaszcza jeśli serwer był wystawiony na publiczny internet w oknie przed Twoją poprawką.
- Szukaj procesów, nasłuchów i wpisów crona, których nie tworzyłeś, oraz połączeń wychodzących od użytkownika workera PHP.
- Porównaj zapisywalne katalogi aplikacji ze źródłem wdrożenia: nowe pliki PHP, zmodyfikowane katalogi uploadów, nieoczekiwanie wykonywalne katalogi tymczasowe.
- Przeszukaj logi WWW pod kątem burz żądań w godzinach ujawnienia, nietypowo dużych treści multipart albo żądań, które zwróciły 500 z sygnaturami OOM w logu błędów PHP.
- Sprawdź, czy faktycznie działa załatany plik binarny — na to pytanie odpowiada powyższe porównanie czasu restartu.
- Jeśli cokolwiek wygląda na podejrzane, potraktuj to jako incydent: zachowaj dysk i logi, wymień wszystkie poświadczenia, do których aplikacja ma dostęp, i przebuduj system ze znanego dobrego obrazu. Przeinstalowanie pakietu PHP na zhakowanym hoście to nie remediacja.
Przykład z własnej infrastruktury
Worldwidetradex.com działa u nas na Ubuntu 24.04 LTS z nginxem i PHP-FPM, więc 22 października wykonaliśmy powyższe sprawdzenia na sobie. Wyniki dobrze pokazują, dlaczego liczenie wersji ma znaczenie:
php -v pokazało PHP 8.3.6 — numer, który na tle upstream PHP wygląda na trzyletnio przestarzały i alarmujący.
dpkg -l pokazało 8.3.6-0ubuntu0.24.04.13, a changelog dystrybucyjny pakietu dla dokładnie tej wersji wymienia CVE-2026-109618 i CVE-2026-109619 jako załatane przez dostawcę. apt-cache policy pokazało wersję zainstalowaną równą kandydatowi, więc nic nowszego nie czekało na instalację.
Wniosek: załatane backportem dystrybucji, obsługiwane przez PHP-FPM zamiast mod_php, z restartem usługi FPM po aktualizacji pakietu. To samo ćwiczenie, pięć komend — i możemy pokazać dowód każdemu klientowi, który zapyta.
Wnioski przenoszą się na każdy stack: Twoje bezpieczeństwo to wersja pakietu plus changelog plus restart, a nie marketingowy numer w panelu hostingu.
Zrób z łatania rutynę, a nie bohaterstwo
PHP2Shell nie zapamiętało się dlatego, że jest egzotyczne; zapamiętało się dlatego, że interpreter, na którym działa większość internetu, miał krytyczny błąd wykonalny przed uwierzytelnieniem i tysiące hostów musiało zareagować w ciągu godzin. Zespoły, które przespały ten czas, nie miały szczęścia — miały automatyzację.
- Nadzorowane aktualizacje bezpieczeństwa interpretera, z automatycznie zapisywaną wersją i czasem restartu.
- Inwentarz, który wie, jakiej SAPI i jakiej gałęzi PHP używa każda witryna, łącznie ze stagingiem, backupami i tamtym jednym WordPressem z 2019 roku.
- Wyćwiczona ścieżka odtworzenia, żeby „łatamy teraz" nigdy nie było ważone przeciwko „nie umiemy wrócić".
- Plan gałęzi: nic na wersji PHP, której wsparcie bezpieczeństwa kończy się w ciągu najbliższych dwunastu miesięcy.
- Jeden imienny właściciel na serwer i pisemna ścieżka eskalacji na dni, w których łatka wypada o 14:00 UTC w środę.
Jeśli wolisz taką zdolność kupić, niż obsadzić ją ludźmi, to przejmujemy produkcyjne platformy PHP — rytm łatek, monitoring, backupy i udokumentowane odtwarzanie — w ramach naszych usług zarządzanej infrastruktury. Zacznij od krótkiego opisu potrzeb i liczb: poproś o wycenę.
Częste pytania
Czy moja witryna na pewno została zhakowana, jeśli działa na niezałatanej wersji PHP?
Niekoniecznie. Niezałatana instalacja PHP wystawiona na internet jest narażona, a skanowanie zaczęło się około godziny ujawnienia, ale narażenie to nie to samo co włamanie. Najpierw załataj, potem wykonaj powyższe kroki weryfikacji; host traktuj jako zhakowany dopiero na podstawie dowodów, a jeśli je znajdziesz — przebuduj go, nie czyść.
Mój host podaje PHP 8.3.6. Czy to jest załatane, czy nie?
To zależy od builda. Pakiety dystrybucyjne niosą poprawki CVE, zachowując numer upstream, więc PHP 8.3.6 z Ubuntu 24.04 albo Debiana może już zawierać obie poprawki. Poproś o pełne oznaczenie pakietu i wiersz changeloga, który wymienia CVE-2026-109618 i CVE-2026-109619; na platformach zarządzanych poproś o datę łatania.
Czy aktualizacje wtyczek, motywów albo frameworka chronią mnie przed PHP2Shell?
Nie. Obie wady leżą w przygotowaniu i zamykaniu żądania przez interpreter PHP, a nie w kodzie aplikacji. Aktualizacje aplikacji to nadal dobra higiena, a WAF spowalnia ruch oportunistyczny, ale tylko aktualizacja interpretera usuwa podatność.
Czy mogę po prostu obniżyć limit pamięci, żeby zablokować błąd braku pamięci?
Odwrotnie. Tymczasowe zalecenie komunikatu dla CVE-2026-109618 to niedopuszczenie, żeby PHP przerywało na własnym suficie pamięci — memory_limit = -1 ustawione tak, by kod aplikacji nie mógł tego nadpisać — a potem ograniczenie złożoności żądań na proxy i objęcie workera limitem kontenera albo cgroupa. Ciasniejszy limit PHP mieści się dokładnie w trybie awarii, który jest tutaj wykorzystywany.
Mamy PHP 8.1 albo starsze, dla których nie było wydania upstream. Co teraz?
Przejdź na wspieraną gałąź, jeśli możesz — to trwałe rozwiązanie. Jeśli nie możesz, weź poprawkę ze swojej dystrybucji albo od dostawcy, bo to jedyne realne źródło, albo nałóż minimalne backporty źródłowe opublikowane przez projekt PHP dla 7.4, 8.0 i 8.1, jeśli budujesz ze źródeł. Zapisz tę decyzję, bo każdego miesiąca zmienia ona Twój profil ryzyka.
Czy aktualizacja PHP 8.3 do 8.3.36 jest ryzykowna dla działającego sklepu?
Aktualizacja bezpieczeństwa w obrębie tej samej wersji podrzędnej zmienia plik binarny interpretera, a nie język, więc większość aplikacji jej nie odczuje. Ryzyko jest operacyjne: częściowe zestawy pakietów, zapomniany restart, konfiguracja ujawniająca się dopiero pod obciążeniem. Zrób snapshot, zaktualizuj cały zestaw pakietów PHP, zrestartuj proces obsługujący żądania i zweryfikuj — a przy złożonej platformie najpierw na stagingu.
Źródła
- PHP — security advisory "Critical remote code execution vulnerabilities, update now" oraz ogłoszenia wydań z 21 października 2026 roku, łącznie z wytycznymi łagodzenia i osią wsparcia na stronie supported versions.
- GitHub Security Advisories dla repozytorium PHP: GHSA-w8hw-w9fx-j79w (CVE-2026-109618) oraz GHSA-6wmf-4rv5-p3rp (CVE-2026-109619).
- CERT-EU — Security Advisory 2026-018, "Critical Vulnerabilities in PHP", wymieniający obie podatności CVE.
- Infosecurity Magazine — "Critical PHP Vulnerabilities Leaked Ahead of Scheduled Security Patches" (21 października 2026) oraz "PHP2Shell Exploitation Attempt Detected by Amazon Four Days Before Vulnerability Disclosure" (22 października 2026).
Chcesz, żeby ktoś przeprowadził aktualizację za Ciebie? Aby porozmawiać o łataniu, audycie wersji, migracji na zarządzaną i załataną platformę PHP albo o otaczającej ją infrastrukturze, skontaktuj się z nami albo zadzwoń pod numer +90 505 679 78 03.