PHP2Shell: sprawdź i załataj luki RCE w PHP na serwerze

PHP2Shell: sprawdź i załataj luki RCE w PHP na serwerze

PHP2Shell: sprawdź i załataj luki RCE w PHP na serwerze

21 października 2026 roku projekt PHP wydał wersje 8.5.12, 8.4.27, 8.3.36 i 8.2.35, które łatają dwie luki w samym PHP, nazwane PHP2Shell. Obie pozwalają, by żądanie od kogoś niezalogowanego uruchomiło kod jako worker PHP. Błąd tkwi w środowisku uruchomieniowym, a nie w WordPressie, Drupalu czy Joomli, więc aktualizacja CMS-a lub jego wtyczek go nie usuwa. Ten poradnik pokazuje, kogo to dotyczy, jak sprawdzić serwer jednym poleceniem, co zrobić już dziś, jeśli nie możesz jeszcze zaktualizować, i jak bezpiecznie przeprowadzić aktualizację.

Czym są te dwie luki

  • CVE-2026-109618, uszkodzenie pamięci przy jej braku - gdy alokacja pamięci się nie powiedzie, PHP może przerwać żądanie w chwili, gdy jego wewnętrzne dane są przygotowane tylko w połowie, a następujące potem sprzątanie ufa tym uszkodzonym danym. Spreparowane żądanie multipart może to wywołać nawet w granicach skonfigurowanych limitów rozmiaru.
  • CVE-2026-109619, nieaktualny stan globalny - stan należący do jednego żądania może przeżyć pamięć, na której się opiera. Kolejne żądanie obsługiwane przez ten sam worker może użyć tej zwolnionej pamięci, zanim zostanie zresetowana (use-after-free). Potwierdzona ścieżka prowadzi przez funkcję session upload progress i błędy krytyczne.

Obie mają ocenę 9.2 (krytyczna) w CVSS 4.0. Według ogłoszenia PHP podczas badań zbudowano działający exploit, a ryzyko jest największe dla Apache z mod_php, gdzie atak wykonuje się przed jakimkolwiek kodem aplikacji. W ciągu kilku dni pojawiło się kilka publicznych exploitów proof-of-concept; Rapid7 podaje, że każdy działa tylko dla jednej kombinacji systemu, wersji PHP i serwera WWW, i odnotował próby wykorzystania. Traktuj to jako pilną łatkę.

Kogo to dotyczy

Każdej instalacji PHP, która obsługuje żądania WWW: PHP-FPM, Apache z mod_php, php-cgi, FrankenPHP i LiteSpeed. To niemal każdy serwer z WordPressem, WooCommerce, Drupalem, Joomlą, Magento, Laravelem i Nextcloudem.

Gałąź PHP Podatne Pierwsza poprawiona wersja
8.5 8.5.0 - 8.5.11 8.5.12
8.4 8.4.0 - 8.4.26 8.4.27
8.3 8.3.0 - 8.3.35 8.3.36
8.2 8.2.0 - 8.2.34 8.2.35
7.4, 8.0, 8.1 wszystkie brak wydania na php.net; backporty w kodzie źródłowym, pakiety dystrybucji lub dostawcy LTS
7.3 i starsze wszystkie brak poprawki

Dystrybucje często zostawiają stary numer wersji i przenoszą poprawkę wstecz (na przykład pakiet Debiana lub Ubuntu, który nadal pokazuje 8.2.x), więc przy PHP z pakietów sprawdzaj pakiet w security trackerze swojej dystrybucji, a nie tylko numer.

Sprawdź serwer jednym poleceniem

Zapisz to jako php2shell-check.php i uruchom tym samym PHP, który obsługuje twoją stronę. Skrypt wypisuje wersję, informację, czy jest starsza od poprawki, oraz dwa ustawienia, które zmieniają opisane niżej doraźne środki.

<?php
// PHP2Shell check: is this PHP build older than the October 21, 2026 fixes?
$fixed = ['8.5' => '8.5.12', '8.4' => '8.4.27', '8.3' => '8.3.36', '8.2' => '8.2.35'];
$branch = PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION;
echo "PHP " . PHP_VERSION . " (" . PHP_SAPI . ")\n";
if (!isset($fixed[$branch])) {
    echo "Branch $branch gets no php.net release: check your distro or LTS vendor, or upgrade to 8.4.\n";
} elseif (version_compare(PHP_VERSION, $fixed[$branch], '<')) {
    echo "VULNERABLE: upgrade to {$fixed[$branch]} or later (or a distro build with the backport).\n";
} else {
    echo "Patched upstream version ({$fixed[$branch]}+).\n";
}
echo "session.upload_progress.enabled = " . (ini_get('session.upload_progress.enabled') ? 'On' : 'Off') . "\n";
echo "post_max_size = " . ini_get('post_max_size') . ", memory_limit = " . ini_get('memory_limit') . "\n";
php php2shell-check.php

Wynik sprawdzony 2026-10-24 w oficjalnych obrazach Docker php:

PHP 8.3.30 (cli)
VULNERABLE: upgrade to 8.3.36 or later (or a distro build with the backport).
session.upload_progress.enabled = On
post_max_size = 8M, memory_limit = 128M
PHP 8.4.27 (cli)
Patched upstream version (8.4.27+).
PHP 7.2.34 (cli)
Branch 7.2 gets no php.net release: check your distro or LTS vendor, or upgrade to 8.4.

php z wiersza poleceń może być innym buildem niż ten, który stoi za stroną. Aby sprawdzić stronę WWW, uruchom php-fpm -v (lub php-fpm8.3 -v w Debianie i Ubuntu) albo umieść skrypt w katalogu głównym serwisu na jedno żądanie i od razu go usuń.

Jeśli nie możesz dziś zaktualizować: środki doraźne

Zespół PHP mówi jasno, że pełnego obejścia nie ma, a aktualizacja to jedyny bezpieczny wybór. Te ustawienia zawężają pole ataku na czas, gdy planujesz aktualizację. Ustaw je tam, gdzie aplikacja nie może ich nadpisać - w php.ini lub w puli FPM przez php_admin_value - bo ini_set() i .user.ini działają za późno. Potem zrestartuj wszystkie workery.

; FPM pool, e.g. /etc/php/8.3/fpm/pool.d/zz-php2shell.conf (the [www] section of your pool)
[www]
php_admin_value[session.upload_progress.enabled] = 0
php_admin_value[post_max_size] = 32M
php_admin_value[upload_max_filesize] = 30M
php-fpm8.3 -t && systemctl restart php8.3-fpm

Sprawdziliśmy ten plik puli poleceniem php-fpm -t na PHP 8.4 (configuration test successful). Co robi każda linia:

  • session.upload_progress.enabled = 0 blokuje potwierdzoną ścieżkę CVE-2026-109619, ale nie każdy wariant. Wyłącz to, chyba że zależy od tego pasek postępu wysyłania plików.
  • post_max_size 8M bez uploadów albo 32M, jeśli strona przyjmuje pliki, z upload_max_filesize poniżej tej wartości, jak zaleca zespół PHP. Ogranicz też rozmiar żądania w nginx (client_max_body_size 32m;) lub Apache (LimitRequestBody).
  • Tylko w PHP 8.5 dodaj fatal_error_backtraces = 0.
  • PHP sugeruje też memory_limit = -1 ustawione przez administratora, aby samego limitu pamięci nie dało się użyć do wywołania CVE-2026-109618. Rób to tylko z limitem pamięci kontenera lub cgroup wokół PHP, inaczej jedno złośliwe żądanie może zająć cały RAM serwera. Nie używaj do tego RLIMIT_AS ani RLIMIT_DATA: mogą one wywołać lukę.

Ukrywanie błędów (display_errors, error_reporting, @) nie pomaga, a pusty log błędów nie dowodzi, że serwer nie został zaatakowany.

Jak zaktualizować

  1. PHP z pakietów (Debian, Ubuntu, RHEL, AlmaLinux). Zainstaluj aktualizację bezpieczeństwa (apt update && apt upgrade lub dnf upgrade 'php*'), a potem zrestartuj PHP-FPM lub Apache, bo działające workery trzymają stary kod. Upewnij się, że changelog pakietu wymienia CVE-2026-109618.
  2. Obrazy Docker. Przebuduj na poprawionym tagu (php:8.4-fpm wskazuje teraz na 8.4.27) poleceniem docker compose build --pull, a potem odtwórz kontenery. Działający kontener zachowuje stare PHP, dopóki nie zostanie zastąpiony.
  3. PHP 7.4 - 8.1. Użyj pakietu z backportem od swojego dostawcy albo przejdź na 8.4. PHP 7.3 i starsze nigdy nie dostaną poprawki: schowaj stronę za listą dozwolonych adresów lub VPN, dopóki nie zostanie zmigrowana.
  4. Po aktualizacji uruchom ponownie skrypt sprawdzający i przejrzyj log serwera WWW pod kątem nietypowych żądań POST multipart i awarii workerów PHP od 21 października.

Jeśli potrzebujesz pomocy, zarządzana administracja serwerami obejmuje takie łatanie, a nasz poradnik o serwerze cloud dla WordPressa pokazuje konfigurację PHP-FPM, która trzyma te ustawienia w puli. Przed aktualizacją strony produkcyjnej zrób snapshot: kopia zapasowa i przywracanie VM wyjaśnia, jak to zrobić.

Co zrobiliśmy

W tym samym tygodniu sprawdziliśmy każdą usługę DCXV działającą na PHP i wdrożyliśmy działania z tego poradnika. Serwerami klientów zarządzają ich właściciele: jeśli używasz PHP na serwerze cloud lub dedykowanym w DCXV, wykonaj powyższe sprawdzenie jeszcze dziś. Nowy serwer cloud dostaje aktualne pakiety przy pierwszym apt upgrade.

Źródła (sprawdzone 2026-10-24): ogłoszenie wydań bezpieczeństwa PHP 8.x z 21 października 2026 roku, biuletyny PHP GHSA-w8hw-w9fx-j79w i GHSA-6wmf-4rv5-p3rp oraz analiza Rapid7.

PHP2Shell: sprawdź i załataj luki RCE w PHP na serwerze
clouddedicatedhosting

PHP2Shell: sprawdź i załataj luki RCE w PHP na serwerze

PHP2Shell (CVE-2026-109618, CVE-2026-109619) pozwala żądaniu bez logowania wykonać kod w PHP. Poprawione wersje, sprawdzony skrypt, obejścia w php.ini i plan aktualizacji.

Brotli CVE-2026-111497: łatka dla Node.js, Bun i Pythona
cloudnetworkinginfrastructure

Brotli CVE-2026-111497: łatka dla Node.js, Bun i Pythona

Luka w dekoderze Brotli (CVE-2026-111497) pozwala uruchomić kod przez fetch() w Node.js i Bun lub klienty HTTP Pythona. Wersje z poprawką, skrypt testowy i przebudowa.

Jak dobrać serwer cloud do SaaS: CPU, RAM, NVMe i backupy
cloudinfrastructurepricing

Jak dobrać serwer cloud do SaaS: CPU, RAM, NVMe i backupy

Dobierz serwer cloud do SaaS w Dockerze i Node.js: budżet pamięci, limity CPU, NVMe i backupy, test obciążeniowy k6, pełna cena miesięczna i arkusz doboru.

Agenty AI do kodu na VPS w UE: utwardzona konfiguracja
aicloudhosting

Agenty AI do kodu na VPS w UE: utwardzona konfiguracja

Uruchom agentów AI do kodu na VPS w UE z ograniczeniami: jednorazowe katalogi, lista dozwolonego ruchu, tokeny, limity, sprawdzony kod, ryzyka i koszt serwera.

Jak przenieść stronę lub aplikację na nowy serwer cloud
cloudhostinginfrastructure

Jak przenieść stronę lub aplikację na nowy serwer cloud

Bezpieczny plan migracji na serwer cloud: checklisty przed, przełączenie i wycofanie, polecenia rsync i bazy danych, TTL DNS, test przez plik hosts i granice.