Stručně: HTTP si mezi dvěma požadavky nic nepamatuje. Relace PHP to řeší: PHP přidělí náhodné ID relace, pošle je prohlížeči jako cookie a příslušná data uloží na serveru, standardně jako soubor. Při každém dalším požadavku načte session_start() data podle ID zpět. K relaci PHP patří i funkce session.upload_progress, kterou php.net kvůli PHP2Shell doporučuje dočasně vypnout na straně serveru.
Proč webové aplikace potřebují relace
Každý požadavek na webový server stojí sám o sobě. Bez doplňkového mechanismu by e-shop při kliknutí na „Košík“ nevěděl, kdo do něj právě něco vložil, a administrace by musela při každém kliknutí žádat heslo. Relace spojují jednotlivé požadavky do sezení.
Pro rozhodovatele to znamená: ID relace má po přihlášení stejnou hodnotu jako uživatelské jméno a heslo dohromady. Pro správce to znamená: kde a jak jsou data relací uložena, je bezpečnostní otázka, zvlášť na serverech s více weby.
Co se děje při session_start()
Průběh je při každém požadavku stejný a lze jej popsat v pěti krocích:
- Prohlížeč pošle s sebou cookie s názvem relace, standardně
PHPSESSID. session_start()přečte ID a předá je obslužnému programu úložiště, standardněfiles.- Obslužný program načte uložená data, PHP je pomocí
serialize_handlerpřevede zpět a naplní$_SESSION. - Skript čte a mění
$_SESSIONjako běžné pole. - Na konci požadavku PHP data zapíše zpět. S
session.lazy_write(výchozí: zapnuto) jen tehdy, pokud se změnila.
<?php
session_start();
$_SESSION['besuche'] = ($_SESSION['besuche'] ?? 0) + 1;
echo 'Seitenaufrufe in dieser Sitzung: ', (int) $_SESSION['besuche'];
Pokud relace ještě neexistuje, PHP vytvoří nové ID a nastaví cookie. Je-li aktivní session.use_strict_mode, PHP odmítne neznámá ID předaná prohlížečem a vytvoří nové. Příručka PHP toto nastavení označuje pro základní bezpečnost za nezbytné.
Výchozí hodnoty, které je dobré znát
Následující hodnoty platí podle příručky PHP, pokud není nastaveno jinak. Mnoho distribucí a poskytovatelů hostingu nastavuje vlastní hodnoty, proto vždy rozhoduje skutečně účinná konfigurace.
| Nastavení | Výchozí | Význam |
|---|---|---|
session.save_handler |
files |
místo uložení dat, možné i Redis nebo databáze |
session.name |
PHPSESSID |
název cookie |
session.serialize_handler |
php |
formát uložených dat |
session.use_strict_mode |
0 |
neznámá ID se přijímají |
session.use_only_cookies |
1 |
žádné ID relace v adrese |
session.cookie_httponly |
0 |
JavaScript může cookie číst |
session.cookie_secure |
0 |
cookie i přes nešifrované HTTP |
session.cookie_samesite |
prázdné | žádný atribut SameSite |
session.gc_maxlifetime |
1440 |
sekundy do možného úklidu |
session.gc_probability / gc_divisor |
1 / 100 |
úklid zhruba při každém stém spuštění |
session.upload_progress.enabled |
1 |
průběh nahrávání se zapisuje do relace |
Hodnoty cookie_httponly, cookie_secure a use_strict_mode tedy nejsou z výroby nastaveny z hlediska bezpečnosti. Jak je správně nastavit, popisuje průvodce Zabezpečení relací v PHP. Nastavení session.sid_length a session.sid_bits_per_character jsou od PHP 8.4.0 označena jako zastaralá.
Přímé nastavování cookies
Vedle cookie relace může aplikace nastavovat vlastní cookies. Od PHP 7.3.0 přijímá setcookie() pro to pole voleb, včetně samesite. Od PHP 8.5.0 přibyla navíc volba partitioned.
<?php
setcookie('sprache', 'de', [
'expires' => time() + 60 * 60 * 24 * 30,
'path' => '/',
'secure' => true,
'httponly' => true,
'samesite' => 'Lax',
]);
Podle příručky musí být u samesite s hodnotou None nastaveno i secure, jinak prohlížeč cookie zablokuje. Cookies jsou data prohlížeče: jejich obsah se při dalším požadavku vrací přes $_COOKIE a je třeba jej ověřovat jako každý jiný vstup. Více na stránce Superglobály.
session.upload_progress: indikátor průběhu nahrávání
PHP může během nahrávání souboru zapisovat průběh do relace. Formulář k tomu posílá skryté pole s názvem z session.upload_progress.name, standardně PHP_SESSION_UPLOAD_PROGRESS. PHP pak ukládá data pod klíčem s předponou upload_progress_ do $_SESSION, s údaji jako čas zahájení, celková velikost a již zpracované bajty.
Důležité pro porozumění: podle příručky zapisuje PHP tyto informace do relace dříve, než se spustí jakýkoli skript. Funkce tedy pracuje během zpracování požadavku, ještě před kódem aplikace. Její nastavení jsou typu INI_PERDIR a nelze je měnit za běhu.
Relace a PHP2Shell: přechodné opatření
Jako jedno z přechodných opatření proti zranitelnostem PHP2Shell uvádí php.net nastavit session.upload_progress.enabled=0 v php.ini, v poolu FPM nebo v konfiguraci serveru a poté restartovat všechny workery, výslovně nikoli přes ini_set() nebo .user.ini. Dne 23. 10. 2026 přibylo upozornění k CVE-2026-115560 se stejným nápravným opatřením do dalšího řádného bugfix vydání.
; Pool FPM webu, poté restartovat všechny workery
php_admin_flag[session.upload_progress.enabled] = off
Podle odborných zpráv toto nastavení samo o sobě neuzavře obě zranitelnosti. Povinná zůstává aktualizace na PHP 8.5.12, 8.4.27, 8.3.36 nebo 8.2.35. Zda vaše aplikace průběh nahrávání vůbec používá a jak nastavení trvale provést, popisuje článek Vypnutí session.upload_progress.
Jak konkrétně pomáhá PHP SOS?
- Zjistíme skutečně účinná nastavení relací pro každý web, nejen hodnoty příkazové řádky.
- Nastavíme přechodná opatření k PHP2Shell pro každý pool, restartujeme všechny workery a ověříme výsledek.
- Místa uložení relací a uživatele poolů mezi weby oddělíme v rámci zpevnění serveru.
- Po incidentu zneplatníme všechny existující relace, aby odcizená ID relací pozbyla hodnoty.
Časté dotazy
Jaký je rozdíl mezi cookie a relací (session)?
Cookie je malý datový záznam, který prohlížeč ukládá a posílá s každým požadavkem. Relace ukládá vlastní data na serveru; v cookie je jen náhodný identifikátor, ID relace.
Jak dlouho žije relace PHP?
Cookie relace platí standardně do zavření prohlížeče. Data na serveru smějí být uklizena po session.gc_maxlifetime, standardně 1440 sekund bez přístupu. Kdy se to skutečně stane, závisí na logice úklidu systému.
Co dělá session.upload_progress?
Funkce zapisuje během nahrávání souboru průběh do relace, aby jej mohl zobrazit druhý požadavek. Je standardně aktivní. Kvůli PHP2Shell php.net doporučuje ji dočasně vypnout na straně serveru.
Stačí session.upload_progress vypnout přes ini_set()?
Ne. Nastavení lze podle příručky za běhu stejně změnit, a php.net výslovně uvádí php.ini, pool FPM nebo konfiguraci serveru jako správná místa, nikoli ini_set() nebo .user.ini. Poté restartovat všechny workery.