Stručne: Nastavte session.upload_progress.enabled=0 v php.ini, v poole PHP-FPM alebo v konfigurácii servera Apache, nikdy cez ini_set() ani .user.ini, a potom reštartujte všetkých workerov PHP. Trvalým sa opatrenie stáva až vtedy, keď je hodnota zablokovaná proti opätovnému zapnutiu, platí v každom spôsobe prevádzky a v každej nainštalovanej verzii PHP a po aktualizáciách sa overuje.
Malé nastavenie s dvojitým účinkom
Zriedka dostalo jediné nastavenie PHP toľko pozornosti. Keď php.net 21. októbra 2026 zverejnil záplaty proti PHP2Shell, bolo session.upload_progress.enabled=0 na zozname prechodných opatrení. O dva dni neskôr nasledoval pokyn k CVE-2026-115560 a odporúčaná náprava bola to isté nastavenie.
Mnohí administrátori ho v tých dňoch rýchlo nastavili. Či pôsobí všade, je iná otázka. Typické medzery sa vymenujú rýchlo: hodnota je len v konfigurácii CLI, druhá verzia PHP sa zabudla, alebo hostingový panel súbor pri najbližšom uložení prepísal. Tento príspevok ukazuje, ako opatrenie zaviesť tak, aby platilo aj o tri mesiace.
Dôležité vopred: vypnutie nenahrádza aktualizáciu PHP. Podľa odborných správ samotné session.upload_progress.enabled=0 neuzavrie obe zraniteľnosti PHP2Shell. Čo presne sa týka CVE-2026-115560, vysvetľuje stránka CVE-2026-115560: upozornenie na priebeh uploadu relácie.
Čo funkcia robí a kto ju potrebuje
Session-Upload-Progress počas nahrávania súboru priebežne zapisuje priebeh do relácie, aby aplikácia mohla zobraziť ukazovateľ priebehu. V PHP je funkcia štandardne zapnutá. Príručka PHP sama upozorňuje, že pritom sa názvy súborov a polí dodané odosielateľom dostávajú nekontrolované do úložiska relácií, a odporúča funkciu vypnúť, ak ju aplikácia nepoužíva.
Či ju vaša aplikácia používa, zistíte čisto čítacím hľadaním v kóde:
# Hľadá použitia funkcie priebehu v kóde aplikácie
grep -rn --include="*.php" -e "upload_progress" -e "PHP_SESSION_UPLOAD_PROGRESS" /var/www/
Ak hľadanie nič nenájde, môžete funkciu vypnúť bez citeľných následkov. Ak sú nálezy, aplikácia stratí len zobrazenie priebehu, nie upload. Moderné formuláre meranie priebehu aj tak zvyčajne robia v prehliadači.
session.upload_progress.enabled nastaviť na správnom mieste
Nastavenie má podľa príručky PHP režim INI_PERDIR. To znamená: dá sa nastaviť v php.ini, v konfigurácii servera, v .htaccess (len mod_php) a v .user.ini (len FPM a CGI), ale nie za behu. php.net vylučuje .user.ini ako miesto pre toto opatrenie výslovne. Nasledujúca tabuľka ukazuje zmysluplné miesta podľa spôsobu prevádzky.
| Spôsob prevádzky | Odporúčané miesto | Blokuje prepísanie? | Potom reštartovať |
|---|---|---|---|
| PHP-FPM | súbor poolu s php_admin_flag |
áno | každú službu FPM |
| PHP-FPM | php.ini FPM SAPI | nie, .user.ini by mohol prepísať |
každú službu FPM |
| Apache s mod_php | VirtualHost alebo konfigurácia servera s php_admin_flag |
áno | Apache úplne |
| php-cgi, LiteSpeed, FrankenPHP | php.ini príslušného behového prostredia | podľa konštrukcie overiť | všetky procesy behového prostredia |
| Obraz Docker | vlastný súbor v /usr/local/etc/php/conf.d/ pri zostavovaní |
áno, ak nie je povolené prepísanie | kontajner vytvoriť znova |
Dva robustné varianty vyzerajú takto:
; PHP-FPM, napr. /etc/php/8.3/fpm/pool.d/seite1.conf
php_admin_flag[session.upload_progress.enabled] = off
# Apache s mod_php, vo VirtualHost alebo na úrovni celého servera
<IfModule php_module>
php_admin_flag session.upload_progress.enabled off
</IfModule>
Dodatočne sa oplatí zápis v php.ini každého webového SAPI ako základnej hodnoty. Potom nastavenie platí aj pre nové pooly, ktoré niekto neskôr vytvorí. Prečo php_admin_flag robí rozdiel, opisuje príspevok php_admin_value: zablokovanie nastavení proti prepísaniu.
Účinnosť overiť vo webovom kontexte
Príkazový riadok často číta inú php.ini než webový server. php -i preto dokazuje málo. Ani php-fpm8.3 -i neukazuje hodnoty z poolov, len hodnoty z php.ini. Spoľahlivý je len dopyt, ktorý skutočne prechádza cez pool.
Postupujte takto:
- Reštartujte všetky služby PHP, napríklad
systemctl restart php8.3-fpmalebo Apache pri mod_php. Bez reštartu beží stará hodnota ďalej. - Do webového koreňového adresára uložte krátky kontrolný súbor s náhodným názvom, ktorý vypíše len aktuálnu hodnotu.
- Súbor raz otvorte cez skutočnú doménu a výsledok zapíšte.
- Súbor okamžite zmažte a krok zopakujte pre každý web a každý pool.
<?php
// Kontrolný súbor: uložiť len nakrátko, potom okamžite zmazať
header('Content-Type: text/plain');
echo 'session.upload_progress.enabled = ', var_export(ini_get('session.upload_progress.enabled'), true), "\n";
echo 'PHP ', PHP_VERSION, ' / SAPI ', PHP_SAPI, "\n";
Očakáva sa prázdna hodnota alebo '0'. Ak tam stojí '1', vaše nastavenie sa v tomto poole neuplatňuje. Po aktualizácii PHP navyše skontrolujte, či sú všetci workeri reštartovaní, ako je opísané v článku Reštart PHP-FPM a všetkých workerov.
Kontrolné súbory nikdy nenechávajte ležať. Prezrádzajú verzie a konfiguráciu a sú obľúbeným cieľom automatizovaných skenov.
Aby nastavenie zostalo trvalé
Väčšina návratov k pôvodnému stavu nevzniká zásahom útočníkov, ale prevádzkou. Nový pool sa skopíruje zo starej šablóny, aktualizácia balíka vytvorí novú php.ini alebo niekto v hostingovom paneli prestaví verziu PHP. Proti takým návratom pomáhajú pevné návyky.
- Pokryť všetky verzie: na mnohých serveroch bežia paralelne viaceré verzie PHP. Každá má vlastné konfiguračné priečinky a potrebuje zápis.
- Upraviť šablóny: šablóny poolov, roly Ansible, súbory Dockerfile a šablóny panela obsahujú hodnotu, aby ju nové weby dedili automaticky.
- Využiť nastavenia panela: v hostingových paneloch patrí hodnota do doplnkových direktív určených panelom, inak ďalšia zmena prepíše ručnú prácu.
- Po aktualizáciách overiť: kontrola z predchádzajúceho oddielu patrí do kontrolného zoznamu každej aktualizácie PHP.
- Zdokumentovať: zapísať dátum, server, pooly a výsledok. To neskôr pomáha voči vedeniu, poisťovni alebo audítorom.
Kto .user.ini vôbec nepoužíva, môže načítavanie takýchto súborov úplne vypnúť pomocou user_ini.filename = v php.ini. To sa však týka všetkých nastavení, ktoré tam aplikácie ukladajú. Tento krok preto vopred otestujte, najmä pri CMS, ktoré zapisujú vlastné súbory .user.ini.
Ostatné prechodné opatrenia php.net, napríklad hranice pre post_max_size a pamäťová hranica cez cgroup, sú zhromaždené pri Okamžité opatrenia, ak ešte nemôžete záplatovať. Ako PHP v zásade usporadúva svoje úrovne konfigurácie, vysvetľuje php.ini vysvetlený.
Ako konkrétne pomáha PHP SOS?
- Zachytiť stav: zistíme všetky verzie PHP, spôsoby prevádzky a pooly na vašich serveroch a vyčítame účinné hodnoty vo webovom kontexte.
- Nastaviť čisto: nastavenie zapíšeme zablokované do poolov a konfigurácie servera a riadene reštartujeme všetkých workerov.
- Otestovať funkciu: formuláre uploadu a správu médií po prechode preveríme.
- Zabrániť návratom: šablóny, nasadenia a nastavenia panela upravíme a stav zdokumentujeme v rámci sprísnenia servera.
Časté otázky
Prečo session.upload_progress.enabled=0 nepôsobí cez ini_set()?
Nastavenie patrí podľa príručky PHP do režimu INI_PERDIR. Preto sa vôbec nedá zmeniť za behu cez ini_set(). php.net uvádza ako správne miesta php.ini, pool FPM alebo konfiguráciu servera a súbor .user.ini výslovne vylučuje.
Fungujú uploady súborov aj po vypnutí?
Áno. Vypína sa len hlásenie o priebehu, ktoré PHP zapisuje do relácie počas uploadu. Samotný upload beží ďalej. Dotknuté sú len aplikácie, ktoré svoj ukazovateľ priebehu stavajú práve na tejto funkcii PHP.
Môže aplikácia funkciu znova zapnúť?
Cez súbor .htaccess pri mod_php alebo súbor .user.ini pri PHP-FPM je to v zásade možné, pokiaľ hodnota nie je zablokovaná. Pomocou php_admin_flag v poole alebo v konfigurácii Apache tomu zabránite.
Musím hodnotu po najbližšej aktualizácii PHP vrátiť späť?
Nie, nie je to potrebné. Funkciu väčšina aplikácií nepotrebuje a príručka PHP sama radí v takých prípadoch ju vypnúť. Po každej aktualizácii len skontrolujte, či hodnota ešte platí.