Stručně: Pomocí PHP disable_functions zakážete funkce, kterými PHP provádí systémové příkazy, například exec, shell_exec nebo proc_open. Útočníkům to po průniku ztíží další krok. Nastavení působí jen z php.ini nebo poolu FPM, musí odpovídat aplikaci a nenahrazuje aktualizaci.
Proč má disable_functions smysl právě teď
U PHP2Shell jde o spuštění škodlivého kódu na dálku bez přihlášení. Obě zranitelnosti, CVE-2026-109618 a CVE-2026-109619, sídlí přímo v interpretu PHP a jsou opraveny v PHP 8.5.12, 8.4.27, 8.3.36 a 8.2.35. Aktualizace je jediná cesta, jak je uzavřít.
Zabezpečení (hardening) míří o úroveň dál. Kdo jednou na serveru spustí kód, chce zpravidla pokračovat: spouštět systémové příkazy, stahovat nástroje, zřídit trvalá zadní vrátka. Mnoho z těchto kroků vede přes několik funkcí PHP. Když jsou zakázané, je cesta namáhavější a nápadnější.
disable_functions proto není náhradou záplat, ale stavebním kamenem pro případ, že přes všechnu opatrnost něco pronikne. Platí to pro budoucí zranitelnosti stejně jako pro PHP2Shell.
Co PHP disable_functions dokáže a co ne
Nastavení odebere uvedené funkce z běhového prostředí. Pokud skript zavolá zakázanou funkci, PHP skončí s chybou. Zákaz platí pro každý kód, který v tomto procesu PHP běží, tedy i pro podstrčený.
Hranice byste měli znát:
- Nastavení není uzavřený ochranný prostor. Rozšíření PHP, chyby v interpretu nebo programy mimo PHP je mohou obejít.
- Nezabrání útočníkovi číst nebo zapisovat soubory, k nimž má uživatel PHP přístup. Za to odpovídají práva k souborům a izolace.
- Působí jen z php.ini nebo jako
php_admin_value. Přesini_set(),.user.iniani.htaccessje nastavit nelze.
Nejvíc disable_functions přinese spolu s čistou php.ini, samostatnými uživateli pro každý web a restriktivními právy k souborům. Základy najdete v příručce Jak bezpečně nakonfigurovat php.ini.
Které funkce byste měli zakázat
Pro typické weby bez potřeby systémových příkazů se osvědčil následující seznam. Zahrnuje funkce pro spouštění procesů a řízení běžících procesů.
| Skupina | Funkce | Typické legitimní využití |
|---|---|---|
| Spouštění příkazů | exec, shell_exec, system, passthru |
Úprava obrázků, zálohy skriptem |
| Otevírání procesů | proc_open, popen |
Composer, nástroje pro PDF, odesílání pošty |
| Řízení procesů | proc_nice, proc_terminate, proc_get_status |
Fronty, úlohy na pozadí |
| Správa procesů | pcntl_exec, pcntl_fork |
většinou jen na příkazové řádce |
| Signály a práva | posix_kill, posix_setuid |
v provozu webu zřídka |
V konfiguraci to vypadá takto:
; php.ini webového provozního režimu, např. /etc/php/8.3/fpm/php.ini
disable_functions = exec,shell_exec,system,passthru,proc_open,popen,proc_nice,proc_terminate,proc_get_status,pcntl_exec,pcntl_fork,posix_kill,posix_setuid
Pokud seznam neplatí pro všechny weby na serveru, nastavte jej pro každý pool FPM zvlášť. Po opětovném načtení ověřte, jaký seznam v tomto poolu skutečně platí:
; /etc/php/8.3/fpm/pool.d/meine-seite.conf (výňatek)
php_admin_value[disable_functions] = exec,shell_exec,system,passthru,proc_open,popen
Předem ověřte aplikaci: tak se vyhnete výpadkům
Kdo seznam nasadí bez kontroly, riskuje, že přestane fungovat zmenšování obrázků, PDF faktury nebo odesílání pošty. Proto předem v kódu vyhledejte dotčené funkce:
# Kde a jak často se funkce v kódu používají?
grep -rnoE "\b(exec|shell_exec|system|passthru|proc_open|popen|pcntl_exec)\s*\(" /var/www/meine-seite --include="*.php" \
| cut -d: -f1 | sort | uniq -c | sort -rn | head -30
Nálezy automaticky neznamenají, že se funkce v provozu skutečně používá. Mnoho knihoven nejprve ověří, zda je funkce dostupná, a jinak zvolí náhradu. Rozhodující je test ve stagingovém prostředí se všemi důležitými procesy: objednávka, faktura, odeslání formuláře, nahrání obrázku, plánované úlohy.
Pokud aplikace jednu z těchto funkcí bezpodmínečně vyžaduje, ověřte systémové požadavky výrobce na jeho oficiální stránce. Úlohu lze často přesunout do samostatného poolu nebo skriptu příkazové řádky, který není dostupný přes web.
Aktivace nastavení a kontrola účinku
Po změně musí PHP konfiguraci znovu načíst. Hodnotu poté ověřte v provozním režimu svého webu, nikoli na příkazové řádce:
sudo systemctl reload php8.3-fpm
php-fpm8.3 -i | grep "^disable_functions"
# V chybovém logu zkontrolovat volání zakázaných funkcí
sudo grep -i "has been disabled" /var/log/php/*.log | tail -20
Hlášení v chybovém logu jsou cenná i později. Pokud se tam náhle objeví volání zakázaných funkcí, ačkoli je vaše aplikace nepoužívá, může to ukazovat na podstrčený kód. Jak pak postupovat dál, popisuje příručka Jak poznat a odstranit webshell.
Typické chyby při použití disable_functions
V praxi zabezpečení málokdy selže na technice, spíš na maličkostech. Tyto chyby jsou obzvlášť časté:
- Změněn špatný soubor: Seznam je jen v php.ini příkazové řádky, web běží přes PHP-FPM a zůstává nechráněn.
- Chybí restart: Soubor je správný, ale běžící procesy pracují dál se starou konfigurací.
- Zakázáno příliš široce: Spolu s ostatními jsou zakázány i funkce jako
ini_setnebomaila důležité procesy bez povšimnutí přestanou fungovat. Chyby se pak často projeví až po dnech, například chybějícími potvrzeními objednávek. - Jednou nastaveno, nikdy neověřeno: Po přestěhování, změně verze PHP nebo nové instalaci přes hostingový panel je seznam pryč.
- Falešný pocit bezpečí: Zákaz je chápán jako náhrada aktualizací. Zranitelnost v interpretu ale neuzavře.
Zařaďte proto kontrolu aktivní hodnoty do své rutiny po každé aktualizaci PHP. Stačí krátký pohled, zabere to minimum času a zabrání tomu, aby se zabezpečení tiše ztratilo.
Při více webech na jednom serveru: zřiďte pro každý web samostatný pool s vlastním seznamem. Doplňkově open_basedir omezuje adresáře, k nimž smí PHP přistupovat.
Jak konkrétně pomáhá PHP SOS?
- Zkontrolujeme kód a procesy vaší aplikace z hlediska používání kritických funkcí.
- Pro každý web stanovíme vhodný seznam zákazů a před spuštěním do ostrého provozu jej otestujeme.
- Zákaz spojíme s pooly, právy k souborům a protokolováním do ucelené koncepce zabezpečení.
- Nastavení zdokumentujeme a sledujeme chybový log kvůli nápadným voláním.
Jak to probíhá jako celek, popisuje služba Zabezpečení serveru pro webové servery PHP.
Časté dotazy
Mohu disable_functions nastavit přes ini_set() nebo .htaccess?
Ne. Nastavení působí jen z php.ini nebo jako php_admin_value v poolu FPM, resp. v konfiguraci Apache. Za běhu je nastavit nelze a aplikace zakázané funkce ani znovu povolit nemůže.
Chrání disable_functions před PHP2Shell?
Ne. PHP2Shell se týká samotného interpretu PHP, zranitelnost uzavře jen aktualizace. Zakázané funkce ale mohou omezit manévrovací prostor útočníka po úspěšném zneužití.
Proč php -i ukazuje jiný seznam než můj web?
Příkazová řádka často čte vlastní php.ini. Pro web platí konfigurace PHP-FPM, mod_php nebo LiteSpeed. Hodnotu proto ověřte v provozním režimu, v němž váš web běží.
Které aplikace potřebují proc_open nebo exec?
Záleží na aplikaci. Typická je úprava obrázků přes externí programy, tvorba PDF, odesílání pošty přes sendmail nebo nástroje jako Composer. Ověřte to v kódu a v systémových požadavcích výrobce.