Ukratko: Kod Nginxa s PHP-FPM-om ranjivost iz PHP2Shella nalazi se u PHP-FPM-u, a ne u Nginxu. Zakrpajte sve PHP-FPM verzije, svaku FPM uslugu potpuno ponovno pokrenite i to dokažite vremenima pokretanja procesa. Za dugoročnu Nginx PHP-FPM sigurnost važni su odvojeni poolovi, vrijednosti koje se ne mogu nadjačati i Nginx konfiguracija koja ne izvršava učitane datoteke.
Kako Nginx i PHP-FPM surađuju
Nginx statične datoteke poslužuje sam, a zahtjeve za PHP skriptama prosljeđuje putem FastCGI-ja PHP-FPM-u. PHP-FPM se sastoji od glavnog procesa i više worker procesa, grupiranih u poolove. Jedan worker uzastopno obrađuje mnogo zahtjeva.
Upravo je to za PHP2Shell relevantno. Kod CVE-2026-109619 unutarnje stanje zahtjeva može ostati sačuvano nakon oslobađanja memorije i iskoristiti ga kasniji zahtjev u istom workeru. Kod CVE-2026-109618 stanje nedostatka memorije (out-of-memory) može prekinuti PHP usred inicijalizacije zahtjeva. Obje ranjivosti ocijenjene su s CVSS v4.0 9,2 i ispravljene su u PHP-u 8.5.12, 8.4.27, 8.3.36 i 8.2.35.
Provjerite stanje: verzije, poolovi, procesi
Mnogi poslužitelji paralelno imaju više PHP-FPM verzija. Sljedeće naredbe samo čitaju; nazivi paketa i usluga su primjeri za Debian/Ubuntu i RHEL obitelj.
# Koje FPM usluge rade?
systemctl list-units --type=service | grep -i fpm
# Koja verzija stoji iza toga? (primjer Debian/Ubuntu)
php-fpm8.3 -v
# RHEL obitelj
php-fpm -v
# Na koje sockete ili portove Nginx prosljeđuje?
nginx -T 2>/dev/null | grep -E 'fastcgi_pass'
# Poolovi i njihovi korisnici
grep -RhE '^\[|^user|^listen' /etc/php/*/fpm/pool.d/ 2>/dev/null
Svaki unos fastcgi_pass uskladite s pokrenutim poolom. Tako vidite koja PHP verzija poslužuje koju web-stranicu. Kod paketa distribucije zakrpu dokazuje zapisnik promjena s CVE brojevima, a ne sam broj verzije.
Čest nalaz kod takvih popisa su poslužitelji na kojima je tijekom godina instalirano više PHP verzija, od kojih se stvarno koristi samo jedna. Ostale FPM usluge ipak i dalje rade, često sa standardnim poolovima koji slušaju na lokalnom socketu ili portu. Izvana najčešće nisu izravno dostupne, ali ostaju nepotreban rizik i produljuju svako hitno ažuriranje. Deaktivirajte i uklonite verzije koje nijedna web-stranica ne koristi, nakon što dodjelu provjerite putem unosa fastcgi_pass.
Isto tako vrijedi pogledati korisnika poolova. Ako svi poolovi rade kao www-data ili nginx, razdvajanje web-stranica postoji samo na papiru. Tko preuzme jednu web-stranicu, može čitati datoteke svih ostalih, primjerice konfiguracijske datoteke s lozinkama baze podataka. Zasebni sistemski korisnici po poolu i odgovarajuća prava nad datotekama stvaraju ovdje stvarnu granicu. To nije mjera protiv PHP2Shella, ali znatno ograničava moguću štetu uspješnog napada.
Instalirajte zakrpu i obnovite sve workere
Nakon ažuriranja paketa svaku PHP-FPM uslugu ponovno pokrenite. Reload doduše zamjenjuje workere, ali potpuni restart obnavlja i glavni proces i nakon sigurnosnih ažuriranja siguran je put.
# Primjer Debian/Ubuntu, po instaliranoj verziji
systemctl restart php8.3-fpm
# RHEL obitelj
systemctl restart php-fpm
# Kontrola: vrijeme pokretanja glavnog procesa i workera
ps -eo pid,lstart,cmd | grep -E 'php-fpm' | grep -v grep
Svaki proces mora biti pokrenut nakon ažuriranja. Opširnije je opisano u članku Ponovno pokretanje PHP-FPM-a i svih workera.
Zakrpa ne uklanja zlonamjerni softver koji je ubačen prije. Sačuvajte Nginx zapisnike pristupa i pogrešaka od 20. 10. 2026. i provjerite web-stranice zbog tragova.
Postavljanje privremenih vrijednosti u poolu
Dok verzija nije zakrpana, php.net preporučuje privremene mjere. One ne pružaju potpunu zaštitu. U PHP-FPM-u vrijednosti postavite s php_admin_value odnosno php_admin_flag u poolu, tada ih aplikacije ne mogu nadjačati putem ini_set().
; Primjer: /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 funkcije uploada php.net navodi post_max_size = 8M. Na PHP-u 8.5 dodaje se fatal_error_backtraces=0. Za napomenu o memory_limit=-1 potrebno je ograničenje memorije na razini cgroupa, primjerice putem MemoryMax u systemd dopuni za FPM uslugu. U Nginxu prilagodite client_max_body_size novoj vrijednosti post_max_size kako bi korisnici dobivali razumljive poruke o pogreškama. Zatim ponovno pokrenite FPM.
Trajno poboljšajte Nginx PHP-FPM sigurnost
Osim akutnog slučaja pomaže nekoliko osnovnih pravila koja ograničavaju štetu kod budućih ranjivosti:
- Jedan pool po web-stranici s vlastitim sistemskim korisnikom, vlastitim socketom i vlastitom granicom
open_basedir. Više u članku open_basedir i izolacija po web-stranici. - Prava nad socketom postavite tako da joj može pristupiti samo Nginx, ne otvarajte FPM portove prema van.
- Izvršavajte samo postojeće skripte: u PHP lokaciji postavite
try_files $uri =404;kako Nginx ne bi prosljeđivao PHP-u putanje koje ne postoje. - Ne izvršavajte uploade: u direktorijima za upload zabranite izvršavanje PHP-a. Napomene su u članku Sigurna provedba uploada datoteka.
- Zaštitite stranice statusa:
pm.status_pathiping.pathučinite dostupnima samo interno.
# Primjer: bez izvršavanja PHP-a u direktoriju za upload
location ~* ^/uploads/.*\.php$ {
deny all;
}
Svaku promjenu provjerite naredbom nginx -t prije ponovnog učitavanja Nginxa. Zabilježite i koji poolovi, verzije i posebna pravila postoje na poslužitelju. Ta kratka dokumentacija kod sljedeće kritične ranjivosti štedi dragocjeno vrijeme jer nitko ne mora tražiti koja je web-stranica vezana za koji pool.
Kako PHP SOS konkretno pomaže?
- Svaku web-stranicu pridružujemo njezinu poolu i PHP verziji te provjeravamo stvarno stanje paketa.
- Zakrpamo, ponovno pokrećemo sve FPM usluge i kao dokaz dokumentiramo vremena pokretanja procesa.
- Do zakrpe privremene vrijednosti postavljamo po poolu i ograničavamo memoriju putem cgroupa.
- U okviru ojačavanja poslužitelja uredno razdvajamo poolove, prava i direktorije za upload.
- Kod sumnje na provalu preuzimamo odgovor na incidente.
Česta pitanja
Je li systemctl reload dovoljan za PHP-FPM nakon ažuriranja?
Reload obnavlja workere, ali glavni proces može zadržati stari kod. Nakon sigurnosnog ažuriranja siguran je put potpuni restart usluge. Zatim provjerite vrijeme pokretanja glavnog procesa i workera.
Treba li Nginx ponovno pokrenuti nakon PHP ažuriranja?
Sam Nginx ne sadrži PHP i za PHP zakrpu ne mora se ponovno pokretati. Ponovno moraju biti pokrenute sve PHP-FPM usluge. Ako pritom mijenjate Nginx konfiguraciju, prije ponovnog učitavanja provjerite je naredbom nginx -t.
Zašto zasebni poolovi po web-stranici?
Svaki pool radi s vlastitim korisnikom i vlastitim ograničenjima. Ako se jedna web-stranica kompromitira, napadač ne dolazi bez daljnjega do datoteka drugih. Osim toga, privremene vrijednosti mogu se ciljano postaviti po poolu.
Je li pm.max_requests zaštita od PHP2Shella?
Ne, ne zamjenjuje zakrpu. Vrijednost ograničava koliko zahtjeva worker obradi prije nego što bude zamijenjen. To može skratiti trajanje stanja u procesu, ali nije mjera koju navodi php.net.