PHP2Shell (CVE-2026-109618 i CVE-2026-109619): Krytyczne podatności RCE w silniku PHP – analiza i metody ich zapobiegania
21 października 2026 roku ujawniono i załatano dwie krytyczne luki bezpieczeństwa w samym rdzeniu interpretera PHP, określane zbiorczo mianem PHP2Shell. Podatności CVE-2026-109618 oraz CVE-2026-109619 otrzymały ocenę 9.2 w skali CVSS v4.0 i pozwalają na zdalne wykonanie kodu (RCE – Remote Code Execution) bez konieczności uwierzytelniania. Ponieważ błędy znajdują się bezpośrednio w silniku języka, zagrożona jest każda aplikacja webowa (w tym WordPress, Magento, Shopware czy WooCommerce) działająca na niezałatanej wersji PHP od linii 5.4 aż do najnowszej 8.5.
Metryczka bezpieczeństwa
| Parametr | Szczegóły |
|---|---|
| Identyfikatory CVE | CVE-2026-109618 (GHSA-w8hw-w9fx-j79w), CVE-2026-109619 (GHSA-6wmf-4rv5-p3rp) |
| Nazwa zwyczajowa | PHP2Shell |
| Klasyfikacja błędów | CWE-824 (Access of Uninitialized Pointer) / Use-After-Free (UAF) |
| Ocena ryzyka | 9.2 (Krytyczna) – CVSS v4.0 |
| Wektor ataku | Sieciowy, niewymagający uwierzytelniania ani interakcji użytkownika |
| Podatne wersje | Wszystkie wersje PHP od 5.4.0 do 8.5.11 (kod podatny od 2012 roku) |
| Wersje załatane | PHP 8.5.12, 8.4.27, 8.3.36, 8.2.35 |
| Odkrywcy | Zespoły badawcze Calif, Wiz Research, OpenAI oraz Quarkslab |
Analiza techniczna: Jak działa PHP2Shell?
Obie luki wynikają z błędnego zarządzania pamięcią podczas nietypowego przerywania żądania HTTP (np. w wyniku błędu krytycznego Fatal Error lub przekroczenia limitu pamięci) za pomocą wywołania longjmp(). Ponieważ proces następuje na poziomie inicjalizacji żądania i parsowania nagłówków (np. multipart/form-data), atak może powieść się zanim wykona się jakakolwiek linijka kodu samej aplikacji.
1. CVE-2026-109618: Uszkodzenie pamięci podczas braku zasobów (Out-of-Memory Corruption)
Gdy przetwarzane żądanie przekroczy zdefiniowany w konfiguracji limit pamięci (memory_limit), silnik PHP natychmiast przerywa bieżącą operację za pomocą skoku longjmp(). Jeśli wyczerpanie pamięci nastąpi w ściśle określonym momencie – gdy wewnętrzne struktury danych żądania są dopiero częściowo zainicjalizowane – procedura czyszcząca (request cleanup) traktuje niepełne, niezainicjalizowane wskaźniki jako prawidłowe dane.
-
Najwyższe ryzyko w
mod_php: Architektura Apachemod_phpuruchamia procedury czyszczące nawet wtedy, gdy sam start żądania zakończy się niepowodzeniem. Umożliwia to przejęcie kontroli nad wskaźnikami i wykonanie kodu na domyślnych ustawieniach serwera. -
Wyciek pamięci w stylu Heartbleed: Błąd ten pozwala również na bezpośredni odczyt zwolnionej pamięci procesu roboczego (workera). Mechanizm śledzenia postępu przesyłania plików (upload-progress handler) może zwrócić zawartość pamięci RAM w ciasteczku odpowiedzi
PHPSESSID. Atakujący może w ten sposób wykraść klucze prywatne TLS, tokeny sesji, hasła oraz klucze API należące do innych użytkowników obsługiwanych przez ten sam proces.
2. CVE-2026-109619: Przestarzały stan globalny (Use-After-Free pomiędzy żądaniami)
Druga podatność dotyczy zachowania stanu wewnętrznego przypisanego do żądania po tym, jak pamięć za nim stojąca została już zwolniona. Kiedy proces roboczy (np. w środowisku PHP-FPM, LiteSpeed czy FrankenPHP) napotyka błąd krytyczny i przerywa działanie, globalne wskaźniki mogą nadal wskazywać na zwolnione obszary pamięci.
Gdy kolejne żądanie HTTP trafia do tego samego procesu roboczego, PHP może odwołać się do tych „wiszących” wskaźników (dangling pointers), zanim standardowa procedura inicjalizacji zdąży je zresetować. Dotyczy to w szczególności dwóch ścieżek:
- Mechanizmu
session.upload_progresspo wystąpieniu błędu braku pamięci (OOM) lub innego błędu krytycznego. - Ścieżki generowania śladu stosu dla błędów krytycznych (fatal error backtrace) w gałęzi PHP 8.5.
Połączenie obu podatności w jeden łańcuch (jak robi to narzędzie eksploatacyjne PHP2Shell) pozwala najpierw zmanipulować układ pamięci, a następnie wykorzystać przejęte struktury do wykonania dowolnych poleceń systemowych z uprawnieniami konta serwera WWW (np. www-data).
Kto jest zagrożony i jak wygląda sytuacja?
Zagrożone są wszystkie konfiguracje obsługujące ruch webowy: PHP-FPM, Apache mod_php, php-cgi, LiteSpeed oraz FrankenPHP. Ponieważ luka tkwi w warstwie C interpretera, popularne systemy CMS i platformy e-commerce (WordPress, Magento, Drupal, PrestaShop, Laravel, Symfony) nie są w stanie obronić się z poziomu własnego kodu PHP – wbudowane w aplikacje „tryby konserwacji” (maintenance mode) nie stanowią żadnej ochrony, gdyż złośliwy ładunek jest przetwarzany przed uruchomieniem skryptu index.php.
Tuż przed publikacją oficjalnych łatek odnotowano pierwsze próby skanowania i ataków w sieci (m.in. w raportach Cloudflare i Sansec). W Holandii szereg kluczowych instytucji (w tym Narodowe Centrum Cyberbezpieczeństwa NCSC, portal Tweakers czy Izba Reprezentantów) profilaktycznie wyłączyło swoje serwisy na czas wdrażania poprawek.
Uwaga dla użytkowników starszych wersji (PHP 8.1 i starsze): Projekt PHP oficjalnie wspiera i załatał wyłącznie gałęzie 8.2, 8.3, 8.4 oraz 8.5. Wersje takie jak PHP 7.4, 8.0 czy 8.1 osiągnęły status End-of-Life (EOL) i nie otrzymają oficjalnych poprawek od twórców języka. Administratorzy korzystający z dystrybucji z długoterminowym wsparciem (np. RHEL, Ubuntu LTS, Debian, AlmaLinux) lub paneli hostingowych (np. Plesk, cPanel) muszą polegać na łatkach backportowanych przez dostawców swojego systemu operacyjnego.
Rekomendacje: Jak zabezpieczyć serwer?
Krok 1: Natychmiastowa aktualizacja PHP (Jedyne pełne rozwiązanie)
Zespół bezpieczeństwa PHP podkreśla, że jedynym w pełni skutecznym sposobem eliminacji zagrożenia jest aktualizacja interpretera do wersji zawierającej poprawki:
- PHP 8.5.12
- PHP 8.4.27
- PHP 8.3.36
- PHP 8.2.35
Ważne: Po zaktualizowaniu pakietów w systemie operacyjnym (lub przebudowaniu obrazów kontenerów Docker/Kubernetes) bezwzględnie wymagany jest restart procesów roboczych (np. systemctl restart php-fpm, systemctl restart apache2), aby nowe biblioteki zostały załadowane do pamięci RAM.
Krok 2: Tymczasowe obejścia (Workarounds) – jeśli nie możesz od razu zaktualizować
Jeżeli natychmiastowa aktualizacja środowiska produkcyjnego nie jest możliwa, należy wdrożyć środki mitygujące na poziomie konfiguracji PHP oraz serwera WWW. Nie eliminują one błędu w stu procentach, ale odcinają potwierdzone wektory eksploatacji.
1. Zmiany w konfiguracji php.ini / puli FPM
Zmiany muszą zostać wymuszone administracyjnie (w głównym pliku php.ini, konfiguracji puli PHP-FPM lub dyrektywach php_admin_value), aby aplikacje ani pliki .user.ini nie mogły ich nadpisać w trakcie trwania żądania:
; Wyłączenie śledzenia postępu uploadu w sesji (zamyka główny wektor CVE-2026-109619)
session.upload_progress.enabled = 0
; Tylko dla PHP 8.5: wyłączenie generowania śladu stosu przy błędach krytycznych
fatal_error_backtraces = 0
; Opcjonalnie dla CVE-2026-109618: wyłączenie przewidywalnego limitu pamięci PHP
; UWAGA: Wiąże się z ryzykiem wyczerpania pamięci RAM całego serwera (DoS)!
memory_limit = -1Po zapisaniu zmian należy zrestartować usługę PHP-FPM / serwer Apache.
2. Blokada żądań multipart/form-data na poziomie serwera WWW lub WAF
Wszystkie znane publicznie exploity wykorzystują żądania typu multipart/form-data (używane m.in. przy przesyłaniu plików), ponieważ są one parsowane przez silnik PHP przed uruchomieniem kodu aplikacji. Jeśli Twoja strona nie wymaga przesyłania plików przez użytkowników, możesz tymczasowo zablokować ten typ żądań:
Konfiguracja dla Nginx (wewnątrz bloku server):
if ($http_content_type ~* "multipart/form-data") {
return 403;
}
Konfiguracja dla Apache (w pliku .htaccess lub konfiguracji VirtualHost):
RewriteEngine On
RewriteCond %{HTTP:Content-Type} multipart/form-data [NC]
RewriteRule ^ - [F]
Wykrywanie kompromitacji (Threat Hunting i IoC)
Ponieważ eksploatacja odbywa się bezpośrednio w pamięci ulotnej przed uruchomieniem właściwej aplikacji, atak może nie zostawić standardowych śladów w logach aplikacyjnych. Podczas audytu systemów pod kątem potencjalnego włamania warto zwrócić uwagę na następujące anomalie:
-
Logi błędów PHP i serwera WWW: Nagły wzrost liczby błędów
Allowed memory size of X bytes exhausted(szczególnie pochodzących z jednego adresu IP lub skierowanych w nietypowe endpointy) połączony z żądaniami POST typumultipart/form-data. -
Crashe procesów roboczych: Wpisy w logach PHP-FPM lub
dmesgwskazujące na nagłe zakończenie procesów potomnych sygnałemSIGSEGV(błąd segmentacji) – często towarzyszące nieudanym próbom wstrzyknięcia kodu lub omijania ASLR. -
Zachowanie procesów (EDR / Auditd): Procesy
php-fpm,httpdlubapache2uruchamiające powłokę systemową (/bin/sh,/bin/bash), narzędzia sieciowe (curl,wget,nc) lub tworzące nowe, nieautoryzowane pliki.php(tzw. webshelle) w katalogach publicznych.
