Na kratko: Pri Nginxu s PHP-FPM je ranljivost PHP2Shell v PHP-FPM, ne v Nginxu. Popravite vse različice PHP-FPM, vsako storitev FPM popolnoma znova zaženite in to dokažite s časi zagona procesov. Za trajno varnost Nginxa s PHP-FPM štejejo ločeni pooli, vrednosti, ki jih ni mogoče prepisati, in konfiguracija Nginxa, ki ne izvaja naloženih datotek.
Kako sodelujeta Nginx in PHP-FPM
Nginx statične datoteke streže sam, zahteve za skripte PHP pa prek FastCGI posreduje PHP-FPM. PHP-FPM sestavljajo glavni proces (master) in več procesov delavcev, združenih v poole. Delavec zaporedoma obdela veliko zahtev.
Prav to je za PHP2Shell pomembno. Pri CVE-2026-109619 lahko notranje stanje zahteve po sprostitvi pomnilnika ostane in ga uporabi poznejša zahteva v istem delavcu. Pri CVE-2026-109618 lahko stanje pomanjkanja pomnilnika (out-of-memory) PHP prekine sredi inicializacije zahteve. Obe ranljivosti imata po CVSS v4.0 oceno 9,2 in sta odpravljeni v PHP 8.5.12, 8.4.27, 8.3.36 in 8.2.35.
Preverite zalogo: različice, pooli, procesi
Mnogi strežniki imajo vzporedno več različic PHP-FPM. Spodnji ukazi samo berejo; imena paketov in storitev so primeri za Debian/Ubuntu in družino RHEL.
# Katere storitve FPM tečejo?
systemctl list-units --type=service | grep -i fpm
# Katera različica je zadaj? (primer Debian/Ubuntu)
php-fpm8.3 -v
# Družina RHEL
php-fpm -v
# Na katere sockete ali vrata Nginx posreduje?
nginx -T 2>/dev/null | grep -E 'fastcgi_pass'
# Pooli in njihovi uporabniki
grep -RhE '^\[|^user|^listen' /etc/php/*/fpm/pool.d/ 2>/dev/null
Vsak vnos fastcgi_pass primerjajte z delujočim poolom. Tako vidite, katera različica PHP streže katero spletno stran. Pri paketih distribucij popravek dokazuje dnevnik sprememb s številkami CVE, ne samo številka različice.
Pogosta najdba pri takih popisih so strežniki, na katerih se je skozi leta namestilo več različic PHP, od katerih se dejansko uporablja samo ena. Preostale storitve FPM kljub temu tečejo naprej, pogosto s privzetimi pooli, ki poslušajo na lokalnem socketu ali vratih. Od zunaj praviloma niso neposredno dosegljive, vendar ostajajo nepotrebno tveganje in podaljšajo vsako nujno posodobitev. Različice, ki jih nobena spletna stran ne uporablja, onemogočite in odstranite, ko preverite dodelitev prek vnosov fastcgi_pass.
Smiseln je tudi pogled na uporabnika poolov. Če vsi pooli tečejo kot www-data ali nginx, je ločitev med spletnimi stranmi samo na papirju. Kdor prevzame eno spletno stran, lahko bere datoteke vseh drugih, na primer konfiguracijske datoteke z gesli zbirke podatkov. Lasten sistemski uporabnik za vsak pool in ustrezne pravice za datoteke tu ustvarijo pravo mejo. To ni ukrep proti PHP2Shell, vendar občutno omeji možno škodo uspešnega napada.
Namestite popravek in obnovite vse delavce
Po posodobitvi paketov znova zaženite vsako storitev PHP-FPM. Reload sicer zamenja delavce, popoln ponovni zagon pa obnovi tudi glavni proces in je po varnostnih posodobitvah varna pot.
# Primer Debian/Ubuntu, za vsako nameščeno različico
systemctl restart php8.3-fpm
# Družina RHEL
systemctl restart php-fpm
# Kontrola: čas zagona glavnega procesa in delavcev
ps -eo pid,lstart,cmd | grep -E 'php-fpm' | grep -v grep
Vsak proces mora biti zagnan po posodobitvi. Podrobno je to opisano na strani Ponovni zagon PHP-FPM in vseh delavcev.
Popravek ne odstrani škodljive programske opreme, ki je bila vnesena prej. Dnevnike dostopov in napak Nginx hranite od 20. 10. 2026 naprej in spletne strani preverite glede sledi.
Vmesne vrednosti nastavite v poolu
Dokler različica ni popravljena, php.net priporoča vmesne ukrepe. Ne nudijo popolne zaščite. V PHP-FPM vrednosti nastavite s php_admin_value oziroma php_admin_flag v poolu, tako jih aplikacije ne morejo prepisati z ini_set().
; Primer: /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
Brez funkcije nalaganja datotek php.net navaja post_max_size = 8M. Pri PHP 8.5 se doda fatal_error_backtraces=0. Za napotek o memory_limit=-1 potrebujete omejitev pomnilnika na ravni cgroup, na primer prek MemoryMax v dopolnilu systemd za storitev FPM. V Nginxu client_max_body_size uskladite z novo vrednostjo post_max_size, da uporabniki dobijo razumljiva sporočila o napakah. Nato znova zaženite FPM.
Trajno izboljšajte varnost Nginx s PHP-FPM
Poleg akutnega primera pomaga nekaj osnovnih pravil, ki omejijo škodo ob prihodnjih ranljivostih:
- En pool za vsako spletno stran z lastnim sistemskim uporabnikom, lastnim socketom in lastno mejo
open_basedir. Več na strani open_basedir in izolacija po spletni strani. - Pravice socketa nastavite tako, da lahko dostopa samo Nginx, vrat FPM ne odpirajte navzven.
- Izvajajte samo obstoječe skripte: v lokaciji PHP nastavite
try_files $uri =404;, da Nginx ne posreduje poti, ki ne obstajajo, PHP-ju. - Ne izvajajte naloženih datotek: v imenikih za nalaganje prepovejte izvajanje PHP. Napotki so na strani Varna izvedba nalaganja datotek.
- Zaščitite statusne strani:
pm.status_pathinping.pathnaj bosta dosegljiva samo interno.
# Primer: brez izvajanja PHP v imeniku za nalaganje
location ~* ^/uploads/.*\.php$ {
deny all;
}
Vsako spremembo preverite z nginx -t, preden Nginx znova naložite. Zapišite tudi, kateri pooli, različice in posebna pravila obstajajo na strežniku. Ta kratka dokumentacija pri naslednji kritični ranljivosti prihrani dragocen čas, ker nihče ne išče, katera spletna stran spada k kateremu poolu.
Kako PHP SOS konkretno pomaga?
- Vsako spletno stran povežemo z njenim poolom in različico PHP ter preverimo dejansko stanje paketov.
- Popravimo, znova zaženemo vse storitve FPM in čase zagona procesov dokumentiramo kot dokaz.
- Do popravka vmesne vrednosti nastavimo za vsak pool in pomnilnik omejimo prek cgroup.
- V okviru utrditve strežnika čisto ločimo poole, pravice in imenike za nalaganje.
- Ob sumu na vlom prevzamemo Incident Response.
Pogosta vprašanja
Ali po posodobitvi za PHP-FPM zadošča systemctl reload?
Reload obnovi delavce, glavni proces (master) pa lahko obdrži staro kodo. Po varnostni posodobitvi je varna pot popoln ponovni zagon storitve. Nato preverite čas zagona glavnega procesa in delavcev.
Ali je treba po posodobitvi PHP znova zagnati tudi Nginx?
Nginx sam ne vsebuje PHP in za popravek PHP ni treba, da se znova zažene. Znova morajo biti zagnane vse storitve PHP-FPM. Če pri tem spreminjate konfiguracijo Nginx, jo pred ponovnim nalaganjem preverite z nginx -t.
Zakaj lasten pool za vsako spletno stran?
Vsak pool teče z lastnim uporabnikom in lastnimi mejami. Če je ena spletna stran kompromitirana, napadalec brez težav ne pride do datotek drugih. Poleg tega je mogoče vmesne vrednosti ciljno nastaviti za vsak pool.
Ali je pm.max_requests zaščita pred PHP2Shell?
Ne, popravka ne nadomešča. Vrednost omejuje, koliko zahtev obdela delavec, preden ga zamenjajo. To lahko skrajša življenjsko dobo stanj v procesu, ni pa ukrep, ki bi ga navajal php.net.