Aktualna sytuacja: PHP2Shell. Dwie krytyczne luki w PHP (CVSS 9,2) umożliwiają wykonanie złośliwego kodu bez logowania. Poprawki od 21.10.2026.Co należy teraz zrobić →

Zabezpieczenie Nginx z PHP-FPM

W Nginx z PHP-FPM bezpieczeństwo opiera się na pulach, uprawnieniach i prawidłowym restarcie. Oto jak załatać po PHP2Shell i trwale utwardzić Nginx oraz PHP-FPM.

Stan 5 min czytaniaSerwery i hosting

Krótko: W Nginx z PHP-FPM luka z PHP2Shell tkwi w PHP-FPM, a nie w Nginx. Proszę załatać wszystkie wersje PHP-FPM, w pełni zrestartować każdą usługę FPM i udokumentować to czasami startu procesów. Dla trwałego bezpieczeństwa Nginx i PHP-FPM liczą się oddzielne pule, wartości niemożliwe do nadpisania oraz konfiguracja Nginx, która nie wykonuje przesłanych plików.

Jak współpracują Nginx i PHP-FPM

Nginx sam wydaje pliki statyczne, a żądania do skryptów PHP przekazuje przez FastCGI do PHP-FPM. PHP-FPM składa się z procesu nadrzędnego (master) i wielu procesów roboczych, pogrupowanych w pule. Jeden proces roboczy obsługuje po kolei wiele żądań.

Właśnie to jest istotne dla PHP2Shell. W przypadku CVE-2026-109619 wewnętrzny stan żądania może po zwolnieniu pamięci pozostać i zostać użyty przez późniejsze żądanie w tym samym procesie roboczym. W przypadku CVE-2026-109618 stan braku pamięci (out-of-memory) może przerwać PHP w trakcie inicjalizacji żądania. Obie luki mają ocenę CVSS v4.0 9.2 i zostały usunięte w PHP 8.5.12, 8.4.27, 8.3.36 i 8.2.35.

Kontrola zasobów: wersje, pule, procesy

Wiele serwerów ma równolegle kilka wersji PHP-FPM. Poniższe polecenia tylko odczytują; nazwy pakietów i usług to przykłady dla Debian/Ubuntu i rodziny RHEL.

# Jakie usługi FPM działają?
systemctl list-units --type=service | grep -i fpm

# Jaka wersja za nimi stoi? (przykład Debian/Ubuntu)
php-fpm8.3 -v
# Rodzina RHEL
php-fpm -v

# Do jakich gniazd lub portów Nginx przekazuje żądania?
nginx -T 2>/dev/null | grep -E 'fastcgi_pass'

# Pule i ich użytkownicy
grep -RhE '^\[|^user|^listen' /etc/php/*/fpm/pool.d/ 2>/dev/null

Proszę porównać każdy wpis fastcgi_pass z działającą pulą. W ten sposób widać, jaka wersja PHP obsługuje którą stronę. W pakietach dystrybucji poprawkę potwierdza dziennik zmian z numerami CVE, a nie sam numer wersji.

Częsty wynik takich inwentaryzacji to serwery, na których przez lata zainstalowano kilka wersji PHP, z których faktycznie używana jest tylko jedna. Pozostałe usługi FPM mimo to działają dalej, często ze standardowymi pulami nasłuchującymi na lokalnym gnieździe lub porcie. Z zewnątrz zwykle nie są bezpośrednio osiągalne, ale pozostają niepotrzebnym ryzykiem i wydłużają każdą awaryjną aktualizację. Proszę wyłączyć i usunąć wersje, z których nie korzysta żadna strona, po sprawdzeniu przypisania przez wpisy fastcgi_pass.

Warto też spojrzeć na użytkownika pul. Jeśli wszystkie pule działają jako www-data lub nginx, rozdział między stronami istnieje tylko na papierze. Kto przejmie jedną stronę, może wtedy czytać pliki wszystkich pozostałych, na przykład pliki konfiguracyjne z hasłami do bazy danych. Osobni użytkownicy systemowi dla każdej puli i odpowiednie prawa do plików tworzą tu prawdziwą granicę. To nie jest środek zaradczy na PHP2Shell, ale znacząco ogranicza możliwe szkody udanego ataku.

Instalacja poprawki i odnowienie wszystkich procesów roboczych

Po aktualizacji pakietów proszę zrestartować każdą usługę PHP-FPM. Reload wymienia wprawdzie procesy robocze, ale dopiero pełny restart odnawia także proces master i jest po aktualizacjach bezpieczeństwa bezpieczną drogą.

# Przykład Debian/Ubuntu, dla każdej zainstalowanej wersji
systemctl restart php8.3-fpm
# Rodzina RHEL
systemctl restart php-fpm

# Kontrola: czas startu procesu master i procesów roboczych
ps -eo pid,lstart,cmd | grep -E 'php-fpm' | grep -v grep

Każdy proces musi być uruchomiony po aktualizacji. Szczegółowo opisuje to artykuł Restart PHP-FPM i wszystkich procesów roboczych.

Ważne

Poprawka nie usuwa szkodliwego oprogramowania wprowadzonego wcześniej. Proszę zachować logi dostępu i błędów Nginx od 20.10.2026 i sprawdzić strony pod kątem śladów.

Ustawianie wartości przejściowych w puli

Dopóki wersja nie jest załatana, php.net zaleca środki przejściowe. Nie dają pełnej ochrony. W PHP-FPM wartości ustawia się przez php_admin_value lub php_admin_flag w puli, wtedy aplikacje nie mogą ich nadpisać przez ini_set().

; Przykład: /etc/php/8.3/fpm/pool.d/website.conf
php_admin_flag[session.upload_progress.enabled] = off
php_admin_value[post_max_size] = 32M
php_admin_value[upload_max_filesize] = 24M

Bez funkcji uploadu php.net podaje post_max_size = 8M. W PHP 8.5 dochodzi fatal_error_backtraces=0. Dla wskazówki dotyczącej memory_limit=-1 potrzebny jest limit pamięci na poziomie cgroup, na przykład przez MemoryMax w uzupełnieniu systemd dla usługi FPM. W Nginx proszę dostosować client_max_body_size do nowego post_max_size, aby użytkownicy otrzymywali zrozumiałe komunikaty o błędach. Potem zrestartować FPM.

Trwała poprawa bezpieczeństwa Nginx PHP-FPM

Poza przypadkiem doraźnym pomaga kilka podstawowych zasad, które ograniczają szkody przy przyszłych lukach:

  • Jedna pula na stronę z własnym użytkownikiem systemowym, własnym gniazdem i własną granicą open_basedir. Więcej w artykule open_basedir i izolacja dla każdej strony.
  • Prawa do gniazda ustawić tak, aby miał do niego dostęp tylko Nginx, nie otwierać portów FPM na zewnątrz.
  • Wykonywać tylko istniejące skrypty: w lokalizacji PHP ustawić try_files $uri =404;, aby Nginx nie przekazywał do PHP ścieżek, które nie istnieją.
  • Nie wykonywać uploadów: w katalogach uploadu zakazać wykonywania PHP. Wskazówki podaje artykuł Bezpieczna obsługa przesyłania plików.
  • Chronić strony statusu: pm.status_path i ping.path udostępnić tylko wewnętrznie.
# Przykład: brak wykonywania PHP w katalogu uploadu
location ~* ^/uploads/.*\.php$ {
    deny all;
}

Proszę sprawdzać każdą zmianę poleceniem nginx -t, zanim przeładują Państwo Nginx. Należy też zapisać, jakie pule, wersje i reguły szczególne istnieją na serwerze. Ta krótka dokumentacja oszczędza cenny czas przy następnej krytycznej luce, bo nikt nie musi najpierw szukać, która strona jest przypisana do której puli.

Jak konkretnie pomaga PHP SOS?

  • Przypisujemy każdą stronę do jej puli i wersji PHP i sprawdzamy rzeczywisty stan pakietów.
  • Łatamy, restartujemy wszystkie usługi FPM i dokumentujemy czasy startu procesów jako dowód.
  • Do czasu poprawki ustawiamy wartości przejściowe dla każdej puli i ograniczamy pamięć przez cgroup.
  • W ramach utwardzania serwerów prawidłowo rozdzielamy pule, uprawnienia i katalogi uploadu.
  • Przy podejrzeniu włamania przejmujemy reagowanie na incydenty.

Częste pytania

Czy systemctl reload dla PHP-FPM wystarczy po aktualizacji?

Reload odnawia procesy robocze, ale proces nadrzędny (master) może zachować stary kod. Po aktualizacji bezpieczeństwa bezpieczną drogą jest pełny restart usługi. Potem proszę sprawdzić czas startu procesu master i procesów roboczych.

Czy Nginx trzeba zrestartować po aktualizacji PHP?

Sam Nginx nie zawiera PHP i nie musi się restartować dla poprawki PHP. Restartować muszą się wszystkie usługi PHP-FPM. Jeśli przy tym zmieniają Państwo konfigurację Nginx, proszę ją sprawdzić przed przeładowaniem poleceniem nginx -t.

Dlaczego osobne pule dla każdej strony?

Każda pula działa z własnym użytkownikiem i własnymi limitami. Jeśli jedna strona zostanie przejęta, atakujący nie dostanie się bez trudu do plików pozostałych. Ponadto wartości przejściowe można ustawiać celowo dla każdej puli.

Czy pm.max_requests chroni przed PHP2Shell?

Nie, nie zastępuje poprawki. Wartość ogranicza liczbę żądań, które proces roboczy obsługuje przed wymianą. Może to skrócić czas życia stanów w procesie, ale nie jest środkiem zaradczym wskazanym przez php.net.

Źródła

Kontakt natychmiast

Liczy się każda godzina. Proszę napisać do nas teraz.

Proszę krótko opisać system, wersję PHP i obserwacje. Skontaktujemy się z Państwem, ustalimy sytuację i będziemy pracować zdalnie, aż incydent zostanie zamknięty i udokumentowany.

Natychmiastowa pomoc