21 października 2026 roku o 14:00 UTC zespół PHP opublikował poprawki dwóch krytycznych podatności, CVE-2026-109618 i CVE-2026-109619, znanych jako PHP2Shell. Zaczęliśmy mniej więcej godzinę później. Około 17:00 UTC wszystkie utrzymywane przez nas serwery były zabezpieczone: 88 projektów objętych naszym wsparciem. Opisujemy tu, jak to zrobiliśmy i co nas spowalniało, bo te same przeszkody czekają na wielu serwerach, których nikt jeszcze nie załatał.
Jeśli chcecie tylko wiedzieć, czy wasza strona jest zagrożona i o co zapytać hosting, przeczytajcie nasz pierwszy artykuł o PHP2Shell.
Pierwsza godzina: odciąć ścieżkę ataku wszędzie
Instalacja poprawionego PHP na kilkudziesięciu serwerach wymaga czasu. Wyłączenie podatnego mechanizmu zajmuje minuty. Dlatego zrobiliśmy to najpierw, na każdym serwerze, zanim zaczęliśmy cokolwiek kompilować.
Komunikat bezpieczeństwa PHP wskazuje session.upload_progress.enabled jako jedną ze ścieżek dla CVE-2026-109619. Wyłączyliśmy to ustawienie w głównej konfiguracji PHP dla każdej wersji PHP na każdym serwerze i zrestartowaliśmy procesy PHP. Komunikat ostrzega, że .user.ini i ini_set() się nie liczą, więc zmienialiśmy pliki na poziomie serwera. Na PHP 8.5 wyłączyliśmy też fatal_error_backtraces, tak jak zaleca komunikat.
To zamknęło tylko potwierdzoną ścieżkę CVE-2026-109619 przez sesje. CVE-2026-109618 wymagała samej aktualizacji.
Trzy rodzaje serwerów, trzy sposoby łatania
Nasze 88 projektów działa na różnych konfiguracjach i każda wymagała własnej drogi.
Serwery z PHP z pakietów dystrybucji. Tu poprawka przychodzi od opiekunów pakietów. Ubuntu wydało poprawione pakiety tego samego dnia. Jedna pułapka dla każdego, kto sprawdza taki serwer: po aktualizacji php -v może nadal pokazywać stary numer, na przykład 8.3.6, bo Ubuntu łata pakiet i zostawia numer wersji. Sprawdzajcie wersję pakietu.
Serwery zarządzane przez panel hostingowy. Kilka serwerów korzysta z aaPanel, który kompiluje własne PHP. W dniu wydania panel nie miał zaktualizowanego PHP. Czekanie na panel oznaczałoby zostawienie tych serwerów otwartych nie wiadomo na jak długo, więc skompilowaliśmy PHP sami.
Kontenery Docker. Część projektów uruchamia PHP w kontenerach zbudowanych z gotowych obrazów. Przebudowa i ponowne wdrożenie całej aplikacji w środku incydentu to dodatkowe ryzyko. Zamiast tego załataliśmy PHP wewnątrz działających kontenerów, a porządną przebudowę obrazów zaplanowaliśmy na później.
Własna kompilacja PHP bez psucia panelu
Kompilacja PHP w panelu różni się od standardowej. Jeśli skompilujecie PHP z domyślnymi opcjami i po prostu je podmienicie, znikną rozszerzenia, a panel przestanie rozpoznawać własne PHP.
Napisaliśmy jeden skrypt kompilacji i uruchamialiśmy go dla każdej wersji PHP na każdym serwerze z panelem:
- odczytuje dokładne opcje configure z już zainstalowanego PHP, żeby nowa kompilacja miała te same rozszerzenia i ścieżki;
- kompiluje poprawioną wersję z oficjalnych źródeł;
- sprawdza, z jakimi bibliotekami OpenSSL i curl linkuje się nowa binarka. Panel linkuje niektóre wersje PHP z własnymi, starszymi kopiami tych bibliotek, więc skrypt pilnuje, żeby nowa kompilacja używała tych samych;
- robi kopię starych binarek, instaluje nowe i restartuje PHP;
- jeśli PHP nie wstanie, sam przywraca stare binarki.
Dzięki skryptowi łataliśmy jedną wersję PHP na jednym serwerze, sprawdzaliśmy strony i powtarzaliśmy na kolejnym, bez ręcznej pracy za każdym razem.
PHP 7.4, 8.0 i 8.1: brak oficjalnego wydania
Zespół PHP nie wydaje już wersji z tych gałęzi. Dla PHP2Shell opublikował tylko zmiany w kodzie źródłowym dla 7.4, 8.0 i 8.1. Część naszych projektów wciąż działa na tych wersjach.
W ich przypadku nałożyliśmy poprawki zespołu PHP na ostatnie wydanie każdej gałęzi i skompilowaliśmy je tym samym skryptem. Opublikowane zmiany dotykają też plików z wersją i list zmian, które nie nakładają się czysto na wydanie, więc wzięliśmy tylko zmiany w kodzie.
Na jednym serwerze działało PHP 7.4 z pakietów Ubuntu 20.04. Dla tego wydania Ubuntu poprawka jest dostępna tylko w ramach rozszerzonego wsparcia bezpieczeństwa Ubuntu (ESM), z którego ten serwer nie korzysta. Skompilowaliśmy PHP 7.4 z tymi samymi flagami kompilacji, których używa Ubuntu, i podmieniliśmy tylko binarkę PHP-FPM, zostawiając oryginał obok. Późniejsza aktualizacja pakietu nadpisze naszą kompilację, więc zapisaliśmy to w dokumentacji projektu.
Kontenery: załatane teraz, przebudowa później
Dla każdego kontenera kompilowaliśmy poprawione PHP w czystej kopii oficjalnego obrazu dla tego samego systemu operacyjnego, a potem kopiowaliśmy do działającego kontenera tylko binarki PHP i potrzebne mu rozszerzenia, z kopią oryginałów w środku.
Jeden obraz oparty na Alpine wymagał tych samych dodatkowych łatek źródeł, które stosuje oficjalny obraz Docker PHP, inaczej kompilacja kończyła się błędem na nowszym kompilatorze.
Haczyk tego podejścia: poprawka żyje tylko do momentu, gdy ktoś odtworzy kontener ze starego obrazu. Jeśli wasz zespół łatał kontenery w ten sposób, wpiszcie przebudowę obrazów do planu, inaczej podatność wróci przy następnym wdrożeniu.
Po aktualizacji: logi
Kiedy na każdym serwerze działało już poprawione PHP, przejrzeliśmy logi serwera WWW i PHP na wszystkich serwerach w poszukiwaniu żądań pasujących do sposobu, w jaki można wykorzystać te podatności. Nie znaleźliśmy śladów wykorzystania luki.
Co powiedzielibyśmy właścicielowi strony po tamtym wieczorze
- Tempo waszego hostingu to wasze tempo. Jeśli PHP pochodzi z panelu albo od dostawcy, który na niego czeka, strona pozostaje otwarta, dopóki oni nie zadziałają. Zapytajcie ich jeszcze dziś, jaką wersję macie.
- Stare PHP wciąż kosztuje. PHP 8.1 i starsze dostały tym razem poprawki wyłącznie w kodzie źródłowym. Następnym razem może nie być nawet tego. Wsparcie dla PHP 8.2 kończy się 31 grudnia 2026 roku.
- Kontenery i własne kompilacje potrzebują opiekuna. Nikt nie aktualizuje ich automatycznie. Ktoś musi wiedzieć, że istnieją, i jak je przebudować.
Nasz automatyczny monitoring działa całą dobę, a inżynierowie reagują, gdy zgłosi incydent.
Jeśli potrzebujecie tego samego na swoich serwerach
Sprawdzimy wersję PHP i zaktualizujemy ją w ciągu jednego dnia roboczego. Napiszcie do nas.
Jeśli potrzebna jest stała opieka, zajrzyjcie na strony o wsparciu serwerów, wsparciu stron internetowych i DevOps. Jeśli wasza aplikacja mobilna korzysta z backendu w PHP, ten backend potrzebuje tej samej aktualizacji; obejmujemy go wsparciem aplikacji mobilnych. Żeby sprawdzić, czy coś jeszcze jest otwarte, zamówcie test penetracyjny.
Źródła
- Komunikat zespołu PHP i środki tymczasowe: https://www.php.net/archive/2026.php
- Komunikaty bezpieczeństwa: https://github.com/php/php-src/security/advisories/GHSA-w8hw-w9fx-j79w i https://github.com/php/php-src/security/advisories/GHSA-6wmf-4rv5-p3rp
- Ubuntu: https://ubuntu.com/blog/php2shell-vulnerability-fixes-available