# Vypnutí session.upload_progress: správně a trvale

> Správné nastavení session.upload_progress.enabled=0: kde hodnota platí, jak ji uzamknout proti opětovnému zapnutí a jak ji bezpečně ověřit z webu.

Zdroj: https://phpsos.de/cs/blog/session-upload-progress-abschalten/  
Stav: 25.10.2026  
Poskytovatel: PHP SOS, Nouzová pomoc pro PHP a bezpečnost serverů. Okamžitá pomoc přes WhatsApp: https://wa.me/491736494914?text=Dobr%C3%BD%20den%2C%20PHP%20SOS%2C%20pot%C5%99ebujeme%20pomoc%20s%20na%C5%A1%C3%ADm%20PHP%20serverem.%20Firma%3A%20%E2%80%A6%20Web%3A%20%E2%80%A6

**Stručně:** Nastavte `session.upload_progress.enabled=0` v php.ini, v poolu PHP-FPM nebo v konfiguraci serveru Apache, nikdy pomocí `ini_set()` ani `.user.ini`, a poté restartujte všechny workery PHP. Trvalým se opatření stane teprve tehdy, když je hodnota uzamčena proti opětovnému zapnutí, platí v každém provozním režimu a každé nainstalované verzi PHP a po aktualizacích se znovu ověřuje.

## Malé nastavení s dvojím účinkem

Málokterému jednotlivému nastavení PHP se dostalo tolik pozornosti. Když php.net 21. října 2026 zveřejnil záplaty proti PHP2Shell, stálo `session.upload_progress.enabled=0` na seznamu přechodných opatření. O dva dny později následovalo upozornění k CVE-2026-115560 a doporučená pomoc byla totéž nastavení.

Mnoho správců ho v těch dnech rychle nastavilo. Zda platí všude, je jiná otázka. Typické mezery se vyjmenují snadno: hodnota je jen v konfiguraci CLI, druhá verze PHP byla zapomenuta, nebo hostingový panel soubor při dalším uložení přepsal. Tento článek ukazuje, jak opatření zavést tak, aby platilo i za tři měsíce.

Důležité předem: Vypnutí nenahrazuje aktualizaci PHP. Podle odborných zpráv samotné `session.upload_progress.enabled=0` neuzavře obě zranitelnosti PHP2Shell. Čeho se CVE-2026-115560 přesně týká, vysvětluje stránka [CVE-2026-115560: upozornění k session upload progress](https://phpsos.de/cs/php2shell/cve-2026-115560/).

## Co funkce dělá a kdo ji potřebuje

Session upload progress během nahrávání souboru průběžně zapisuje postup do session, aby aplikace mohla zobrazit ukazatel průběhu. V PHP je funkce standardně zapnutá. Příručka PHP sama upozorňuje, že přitom se názvy souborů a polí dodané odesílatelem dostanou nekontrolovaně do úložiště session, a doporučuje funkci vypnout, pokud ji aplikace nepoužívá.

Zda ji vaše aplikace používá, zjistíte čistě čtecím hledáním v kódu:

```bash
# Hledá použití funkce průběhu v kódu aplikace
grep -rn --include="*.php" -e "upload_progress" -e "PHP_SESSION_UPLOAD_PROGRESS" /var/www/
```

Pokud hledání nic nenajde, můžete funkci vypnout bez znatelných následků. Pokud jsou nálezy, aplikace ztratí jen zobrazení průběhu, ne nahrávání. Moderní formuláře měří průběh většinou stejně v prohlížeči.

## Nastavit session.upload_progress.enabled na správném místě

Nastavení má podle příručky PHP režim `INI_PERDIR`. To znamená: lze ho zadat v php.ini, v konfiguraci serveru, v `.htaccess` (jen mod_php) a v `.user.ini` (jen FPM a CGI), ale ne za běhu. php.net vylučuje `.user.ini` jako místo pro toto opatření. Následující tabulka ukazuje rozumná místa podle provozního režimu.

| Provozní režim | Doporučené místo | Uzamkne proti přepsání? | Poté restartovat |
|---|---|---|---|
| PHP-FPM | soubor poolu s `php_admin_flag` | ano | každou službu FPM |
| PHP-FPM | php.ini SAPI FPM | ne, `.user.ini` by mohl přepsat | každou službu FPM |
| Apache s mod_php | VirtualHost nebo konfigurace serveru s `php_admin_flag` | ano | Apache celý |
| php-cgi, LiteSpeed, FrankenPHP | php.ini příslušného běhového prostředí | ověřit podle uspořádání | všechny procesy běhového prostředí |
| Image Dockeru | vlastní soubor v `/usr/local/etc/php/conf.d/` při sestavení | ano, pokud není povoleno přepsání | kontejner vytvořit znovu |

Obě robustní varianty vypadají takto:

```ini
; PHP-FPM, např. /etc/php/8.3/fpm/pool.d/seite1.conf
php_admin_flag[session.upload_progress.enabled] = off
```

```apache
# Apache s mod_php, ve VirtualHost nebo pro celý server
<IfModule php_module>
    php_admin_flag session.upload_progress.enabled off
</IfModule>
```

Navíc se vyplatí zápis v php.ini každého webového SAPI jako základní hodnota. Pak nastavení platí i pro nové pooly, které někdo později založí. Proč `php_admin_flag` dělá rozdíl, popisuje článek [php_admin_value: uzamknutí nastavení proti přepsání](https://phpsos.de/cs/blog/php-admin-value-sperren/).

## Ověřit účinnost z webu

Příkazová řádka často čte jiné php.ini než webový server. `php -i` proto dokazuje málo. Také `php-fpm8.3 -i` ukazuje jen hodnoty z php.ini, ne zápisy z poolů. Spolehlivý je jen dotaz, který skutečně běží přes pool.

Postupujte takto:

1. Restartujte všechny služby PHP, například `systemctl restart php8.3-fpm`, nebo Apache u mod_php. Bez restartu běží stará hodnota dál.
2. Do webrootu umístěte krátký kontrolní soubor s náhodným názvem, který vypíše jen aktuální hodnotu.
3. Soubor jednou zavolejte přes skutečnou doménu a zapište výsledek.
4. Soubor ihned smažte a krok zopakujte pro každý web a každý pool.

```php
<?php
// Kontrolní soubor: umístit jen krátce, poté ihned smazat
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čekává se prázdná hodnota nebo `'0'`. Pokud tam stojí `'1'`, vaše nastavení se v tomto poolu neuplatňuje. Po aktualizaci PHP navíc zkontrolujte, zda jsou restartováni všichni workeři, jak je popsáno v článku [Restart PHP-FPM a všech workerů](https://phpsos.de/cs/php2shell/php-fpm-neustart/).

> **Důležité:**
> Kontrolní soubory nikdy nenechávejte ležet. Prozrazují verze a konfiguraci a jsou oblíbeným cílem automatizovaných skenů.

## Aby nastavení trvale zůstalo

Většina návratů ke starému stavu nevzniká útočníky, ale provozem. Nový pool se zkopíruje ze staré šablony, aktualizace balíčku vytvoří nové php.ini, nebo někdo v hostingovém panelu přepne verzi PHP. Proti takovým návratům pomáhají pevné návyky.

- **Pokrýt všechny verze:** Na mnoha serverech běží paralelně několik verzí PHP. Každá má vlastní konfigurační složky a potřebuje zápis.
- **Upravit šablony:** Šablony poolů, role Ansible, soubory Dockerfile a šablony panelů obsahují hodnotu, aby ji nové weby dědily automaticky.
- **Využívat nastavení panelu:** V hostingových panelech patří hodnota do dodatečných direktiv, které panel předvídá, jinak další změna ruční práci přepíše.
- **Po aktualizacích ověřit:** Kontrola z předchozího oddílu patří do kontrolního seznamu každé aktualizace PHP.
- **Dokumentovat:** Zaznamenat datum, server, pooly a výsledek. To později pomůže vůči vedení, pojišťovně nebo auditorům.

Kdo `.user.ini` vůbec nepoužívá, může načítání takových souborů úplně vypnout pomocí `user_ini.filename =` v php.ini. Týká se to ale všech nastavení, která tam aplikace ukládají. Tento krok proto předem otestujte, zejména u CMS, která zapisují vlastní soubory `.user.ini`.

Ostatní přechodná opatření od php.net, například limity pro `post_max_size` a limit paměti přes cgroup, jsou souhrnně na stránce [Okamžitá opatření, když zatím nemůžete záplatovat](https://phpsos.de/cs/php2shell/sofortmassnahmen-ohne-patch/). Jak PHP zásadně řadí své úrovně konfigurace, vysvětluje [php.ini vysvětleno](https://phpsos.de/cs/php/php-ini-erklaert/).

## Jak konkrétně pomáhá PHP SOS?

- **Zjistit stav:** Zmapujeme všechny verze PHP, provozní režimy a pooly na vašich serverech a načteme platné hodnoty z webu.
- **Nastavit čistě:** Nastavení zapíšeme uzamčené do poolů a konfigurace serveru a kontrolovaně restartujeme všechny workery.
- **Otestovat funkci:** Formuláře pro nahrávání a správu médií po přechodu zkontrolujeme.
- **Zabránit návratům:** Šablony, nasazení a nastavení panelů upravíme a stav zdokumentujeme v rámci [zpevnění serveru](https://phpsos.de/cs/leistungen/server-haertung/).


## Časté dotazy

**Proč session.upload_progress.enabled=0 nefunguje přes ini_set()?**  
Podle příručky PHP patří nastavení do režimu INI_PERDIR. Proto ho nelze za běhu měnit pomocí ini_set(). php.net uvádí jako správná místa php.ini, pool FPM nebo konfiguraci serveru a .user.ini výslovně vylučuje.

**Funguje nahrávání souborů i po vypnutí?**  
Ano. Vypne se jen hlášení průběhu, které PHP během nahrávání zapisuje do session. Samotné nahrávání běží dál. Dotčeny jsou jen aplikace, které svůj ukazatel průběhu staví právě na této funkci PHP.

**Může aplikace funkci znovu zapnout?**  
Přes soubor .htaccess u mod_php nebo .user.ini u PHP-FPM je to v zásadě možné, dokud hodnota není uzamčena. Pomocí php_admin_flag v poolu nebo v konfiguraci Apache tomu zabráníte.

**Musím hodnotu po příští aktualizaci PHP vrátit zpět?**  
Ne, není to nutné. Většina aplikací funkci nepotřebuje a příručka PHP sama radí ji v takových případech vypnout. Po každé aktualizaci jen ověřte, zda hodnota stále platí.

## Zdroje

- [php.net: bezpečnostní oznámení](https://www.php.net/)
- [Příručka PHP: konfigurace session](https://www.php.net/manual/en/session.configuration.php)
- [Příručka PHP: soubory .user.ini](https://www.php.net/manual/en/configuration.file.per-user.php)
