# Seje in piškotki v PHP

> Kako delujejo seje in piškotki PHP: ID seje, shranjevanje, privzete vrednosti php.ini, napredek nalaganja in prehodni ukrep proti PHP2Shell.

Vir: https://phpsos.de/sl/php/sessions-und-cookies/  
Stanje: 25.10.2026  
Ponudnik: PHP SOS, Nujna pomoč za PHP in varnost strežnikov. Takojšnja pomoč po WhatsAppu: https://wa.me/491736494914?text=Pozdravljeni%2C%20PHP%20SOS%2C%20potrebujemo%20pomo%C4%8D%20z%20na%C5%A1im%20stre%C5%BEnikom%20PHP.%20Podjetje%3A%20%E2%80%A6%20Spletna%20stran%3A%20%E2%80%A6

**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:

1. Brskalnik pošlje piškotek z imenom seje, privzeto `PHPSESSID`.
2. `session_start()` prebere ID in ga preda handlerju za shranjevanje, privzeto `files`.
3. Handler naloži shranjene podatke, PHP jih s `serialize_handler` pretvori nazaj in napolni `$_SESSION`.
4. Skripta `$_SESSION` bere in spreminja kot navadno polje.
5. Ob koncu zahteve PHP podatke zapiše nazaj. Z `session.lazy_write` (privzeto: vklopljeno) samo, če so se spremenili.

```php
<?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](https://phpsos.de/sl/ratgeber/session-sicherheit-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
<?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](https://phpsos.de/sl/php/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](https://phpsos.de/sl/php2shell/cve-2026-115560/), z isto rešitvijo do naslednje redne izdaje s popravki.

```ini
; 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](https://phpsos.de/sl/blog/session-upload-progress-abschalten/).

## 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](https://phpsos.de/sl/leistungen/server-haertung/).
- 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.

## Viri

- [Priročnik PHP: konfiguracija sej](https://www.php.net/manual/de/session.configuration.php)
- [Priročnik PHP: napredek nalaganja v seji](https://www.php.net/manual/de/session.upload-progress.php)
- [Priročnik PHP: setcookie](https://www.php.net/manual/en/function.setcookie.php)
- [php.net: varnostna obvestila](https://www.php.net/)
