Na kratko: HTTP si med dvema zahtevama ne zapomni ničesar. Seja PHP to reši: PHP dodeli naključen ID seje, ga kot piškotek pošlje brskalniku in pripadajoče podatke shrani na strežniku, privzeto kot datoteko. Ob vsaki nadaljnji zahtevi session_start() podatke po ID znova prebere. K seji PHP sodi tudi funkcija session.upload_progress, ki jo php.net zaradi PHP2Shell priporoča začasno izklopiti na strani strežnika.
Zakaj spletne aplikacije potrebujejo seje
Vsaka zahteva spletnemu strežniku stoji zase. Brez dodatnega mehanizma spletna trgovina ob kliku na „Košarica“ ne bi več vedela, kdo je pravkar nekaj vanjo dal, skrbniško območje pa bi moralo ob vsakem kliku znova vprašati za geslo. Seje posamezne zahteve povežejo v sejo.
Za odločevalce to pomeni: ID seje je po prijavi vreden toliko kot uporabniško ime in geslo skupaj. Za skrbnike to pomeni: kje in kako ležijo podatki seje, je varnostno vprašanje, še posebej na strežnikih z več spletnimi stranmi.
Kaj se zgodi ob session_start()
Potek je ob vsaki zahtevi enak in ga je mogoče opisati v petih korakih:
- Brskalnik pošlje piškotek z imenom seje, privzeto
PHPSESSID. session_start()prebere ID in ga preda handlerju za shranjevanje, privzetofiles.- Handler naloži shranjene podatke, PHP jih s
serialize_handlerpretvori nazaj in napolni$_SESSION. - Skripta
$_SESSIONbere in spreminja kot navadno polje. - Ob koncu zahteve PHP podatke zapiše nazaj. Z
session.lazy_write(privzeto: vklopljeno) samo, če so se spremenili.
<?php
session_start();
$_SESSION['besuche'] = ($_SESSION['besuche'] ?? 0) + 1;
echo 'Seitenaufrufe in dieser Sitzung: ', (int) $_SESSION['besuche'];
Če seje še ni, PHP ustvari nov ID in nastavi piškotek. Če je session.use_strict_mode aktiven, PHP zavrne neznane ID, ki jih določi brskalnik, in ustvari nov. Priročnik PHP to nastavitev za osnovno varnost označuje kot obvezno.
Privzete vrednosti, ki jih je dobro poznati
Naslednje vrednosti po priročniku PHP veljajo, kadar ni konfigurirano nič drugega. Številne distribucije in ponudniki gostovanja nastavijo lastne vrednosti, zato vedno šteje dejansko veljavna konfiguracija.
| Nastavitev | Privzeto | Pomen |
|---|---|---|
session.save_handler |
files |
mesto shranjevanja podatkov, mogoč je tudi Redis ali podatkovna zbirka |
session.name |
PHPSESSID |
ime piškotka |
session.serialize_handler |
php |
oblika shranjenih podatkov |
session.use_strict_mode |
0 |
neznani ID se sprejmejo |
session.use_only_cookies |
1 |
brez ID seje v naslovu |
session.cookie_httponly |
0 |
JavaScript lahko prebere piškotek |
session.cookie_secure |
0 |
piškotek tudi prek nešifriranega HTTP |
session.cookie_samesite |
prazno | brez atributa SameSite |
session.gc_maxlifetime |
1440 |
sekunde do možnega čiščenja |
session.gc_probability / gc_divisor |
1 / 100 |
čiščenje ob približno vsakem stotem zagonu |
session.upload_progress.enabled |
1 |
napredek nalaganja se zapisuje v sejo |
Vrednosti za cookie_httponly, cookie_secure in use_strict_mode torej od tovarne niso zasnovane za varnost. Kako jih pravilno nastavite, opisuje vodnik Zavarovanje sej v PHP. Nastavitvi session.sid_length in session.sid_bits_per_character sta od PHP 8.4.0 označeni kot zastareli.
Neposredno nastavljanje piškotkov
Poleg piškotka seje lahko aplikacija nastavlja lastne piškotke. Od PHP 7.3.0 setcookie() za to sprejme polje z možnostmi, vključno s samesite. Od PHP 8.5.0 obstaja še možnost partitioned.
<?php
setcookie('sprache', 'de', [
'expires' => time() + 60 * 60 * 24 * 30,
'path' => '/',
'secure' => true,
'httponly' => true,
'samesite' => 'Lax',
]);
Po priročniku mora biti pri samesite z vrednostjo None nastavljen tudi secure, sicer brskalnik piškotek blokira. Piškotki so podatki brskalnika: njihova vsebina se ob naslednji zahtevi vrne prek $_COOKIE in jo je treba preveriti kot vsak drug vnos. Več na strani Superglobals.
session.upload_progress: prikaz napredka nalaganj
PHP lahko med nalaganjem datoteke napredek zapiše v sejo. Za to obrazec pošlje skrito polje z imenom iz session.upload_progress.name, privzeto PHP_SESSION_UPLOAD_PROGRESS. PHP nato podatke shrani v $_SESSION pod ključem s predpono upload_progress_, s podatki, kot so čas začetka, skupna velikost in že obdelani bajti.
Pomembno za razumevanje: po priročniku PHP te informacije zapiše v sejo, preden se izvede katera koli skripta. Funkcija torej deluje med obdelavo zahteve, še pred kodo aplikacije. Njene nastavitve so tipa INI_PERDIR in jih med izvajanjem ni mogoče spremeniti.
Seje in PHP2Shell: prehodni ukrep
Kot enega od prehodnih ukrepov proti ranljivostma PHP2Shell php.net navaja, da se session.upload_progress.enabled=0 nastavi v php.ini, v poolu FPM ali v konfiguraciji strežnika ter nato znova zaženejo vsi workerji, izrecno ne prek ini_set() ali .user.ini. Dne 23. 10. 2026 je prišlo še obvestilo o CVE-2026-115560, z isto rešitvijo do naslednje redne izdaje s popravki.
; pool FPM spletne strani, nato znova zagnati vse workerje
php_admin_flag[session.upload_progress.enabled] = off
Po strokovnih poročilih ta nastavitev sama ne zapre obeh ranljivosti. Obvezna ostane posodobitev na PHP 8.5.12, 8.4.27, 8.3.36 ali 8.2.35. Ali vaša aplikacija napredek nalaganja sploh uporablja in kako nastavitev nastavite trajno, opisuje prispevek Izklop session.upload_progress.
Kako PHP SOS pomaga konkretno?
- Za vsako spletno stran preberemo dejansko veljavne nastavitve sej, ne samo vrednosti ukazne vrstice.
- Prehodne ukrepe proti PHP2Shell nastavimo za vsak pool, znova zaženemo vse workerje in preverimo rezultat.
- Mesta shranjevanja sej in uporabnike poolov med spletnimi stranmi ločimo v okviru utrjevanja strežnika.
- Po incidentu zavržemo vse obstoječe seje, da ukradeni ID sej postanejo brez vrednosti.
Pogosta vprašanja
Kakšna je razlika med piškotkom in sejo?
Piškotek je majhen zapis, ki ga brskalnik shrani in pošlje ob vsaki zahtevi. Seja dejanske podatke shrani na strežniku; v piškotku je samo naključna oznaka, ID seje.
Kako dolgo živi seja PHP?
Piškotek seje privzeto velja, dokler se brskalnik ne zapre. Podatke na strežniku je dovoljeno počistiti po session.gc_maxlifetime, privzeto 1440 sekund brez dostopa. Kdaj se to dejansko zgodi, je odvisno od logike čiščenja sistema.
Kaj počne session.upload_progress?
Funkcija med nalaganjem datoteke napredek zapiše v sejo, da ga lahko prikaže druga zahteva. Privzeto je aktivna. Zaradi PHP2Shell php.net priporoča, da jo začasno izklopite na strani strežnika.
Ali zadošča, da session.upload_progress izklopim z ini_set()?
Ne. Nastavitve po priročniku med izvajanjem sploh ni mogoče spremeniti, php.net pa kot prava mesta izrecno navaja php.ini, pool FPM ali konfiguracijo strežnika, ne ini_set() ali .user.ini. Nato znova zaženite vse workerje.