# Istunnot ja evästeet PHP:ssä

> Miten PHP-istunnot ja evästeet toimivat: istuntotunnus, tallennus, php.ini-oletusarvot, latauksen eteneminen ja PHP2Shellin väliaikaistoimi.

Lähde: https://phpsos.de/fi/php/sessions-und-cookies/  
Tilanne: 25.10.2026  
Palveluntarjoaja: PHP SOS, PHP-hätäapu ja palvelimen tietoturva. Pikaapu WhatsAppilla: https://wa.me/491736494914?text=Hei%20PHP%20SOS%2C%20tarvitsemme%20apua%20PHP-palvelimemme%20kanssa.%20Yritys%3A%20%E2%80%A6%20Verkkosivusto%3A%20%E2%80%A6

**Lyhyesti:** HTTP ei muista mitään kahden pyynnön välillä. PHP-istunto ratkaisee tämän: PHP antaa satunnaisen istuntotunnuksen, lähettää sen selaimelle evästeenä ja tallentaa siihen kuuluvat tiedot palvelimelle, oletuksena tiedostona. Jokaisella seuraavalla pyynnöllä `session_start()` lukee tiedot takaisin tunnuksen perusteella. PHP-istuntoon kuuluu myös toiminto `session.upload_progress`, jonka php.net suosittelee PHP2Shellin vuoksi sammuttamaan tilapäisesti palvelinpuolella.

## Miksi verkkosovellukset tarvitsevat istuntoja

Jokainen verkkopalvelimelle tehty pyyntö on itsenäinen. Ilman lisämekanismia verkkokauppa ei enää tietäisi ”Ostoskori”-painiketta napsautettaessa, kuka juuri lisäsi siihen jotakin, ja ylläpitoalue joutuisi kysymään salasanan jokaisella klikkauksella. Istunnot yhdistävät yksittäiset pyynnöt istunnoksi.

Päättäjälle tämä tarkoittaa: istuntotunnus on kirjautumisen jälkeen yhtä arvokas kuin käyttäjätunnus ja salasana yhdessä. Ylläpitäjälle: se, missä ja miten istuntotiedot sijaitsevat, on tietoturvakysymys, erityisesti usean verkkosivuston palvelimilla.

## Mitä session_start() tekee

Kulku on jokaisella pyynnöllä sama ja sen voi kuvata viidessä vaiheessa:

1. Selain lähettää mukana evästeen, jonka nimi on istunnon nimi, oletuksena `PHPSESSID`.
2. `session_start()` lukee tunnuksen ja välittää sen tallennuskäsittelijälle, oletuksena `files`.
3. Käsittelijä lataa tallennetut tiedot, PHP muuntaa ne takaisin `serialize_handler`-käsittelijällä ja täyttää `$_SESSION`-muuttujan.
4. Komentosarja lukee ja muuttaa `$_SESSION`-muuttujaa kuin tavallista taulukkoa.
5. Pyynnön lopussa PHP kirjoittaa tiedot takaisin. Asetuksella `session.lazy_write` (oletus: päällä) vain, jos ne ovat muuttuneet.

```php
<?php
session_start();

$_SESSION['besuche'] = ($_SESSION['besuche'] ?? 0) + 1;
echo 'Seitenaufrufe in dieser Sitzung: ', (int) $_SESSION['besuche'];
```

Jos istuntoa ei vielä ole, PHP luo uuden tunnuksen ja asettaa evästeen. Jos `session.use_strict_mode` on aktiivinen, PHP hylkää selaimen antamat tuntemattomat tunnukset ja luo uuden. PHP-käsikirja kutsuu tätä asetusta perustason tietoturvalle välttämättömäksi.

## Oletusarvot, jotka kannattaa tuntea

Seuraavat arvot pätevät PHP-käsikirjan mukaan, kun mitään muuta ei ole konfiguroitu. Monet jakelut ja hosting-yritykset asettavat omat arvonsa, joten ratkaisevaa on aina todella voimassa oleva konfiguraatio.

| Asetus | Oletus | Merkitys |
|---|---|---|
| `session.save_handler` | `files` | tietojen tallennuspaikka, myös Redis tai tietokanta mahdollinen |
| `session.name` | `PHPSESSID` | evästeen nimi |
| `session.serialize_handler` | `php` | tallennettujen tietojen muoto |
| `session.use_strict_mode` | `0` | tuntemattomat tunnukset hyväksytään |
| `session.use_only_cookies` | `1` | ei istuntotunnusta osoitteessa |
| `session.cookie_httponly` | `0` | JavaScript voi lukea evästeen |
| `session.cookie_secure` | `0` | eväste myös salaamattoman HTTP:n yli |
| `session.cookie_samesite` | tyhjä | ei SameSite-attribuuttia |
| `session.gc_maxlifetime` | `1440` | sekuntia mahdolliseen siivoukseen |
| `session.gc_probability` / `gc_divisor` | `1` / `100` | siivous noin joka sadannella käynnistyksellä |
| `session.upload_progress.enabled` | `1` | latauksen eteneminen kirjoitetaan istuntoon |

Arvot `cookie_httponly`, `cookie_secure` ja `use_strict_mode` eivät siis ole tehtaalta lähtien tietoturvaa varten asetettuja. Miten ne asetetaan oikein, kuvaa opas [Istuntojen suojaus PHP:ssä](https://phpsos.de/fi/ratgeber/session-sicherheit-php/). Asetukset `session.sid_length` ja `session.sid_bits_per_character` on merkitty vanhentuneiksi versiosta PHP 8.4.0 lähtien.

## Evästeiden asettaminen suoraan

Istuntoevästeen lisäksi sovellus voi asettaa omia evästeitä. Versiosta PHP 7.3.0 lähtien `setcookie()` ottaa tähän vastaan asetustaulukon, myös `samesite`-asetuksen. Versiosta PHP 8.5.0 lähtien mukana on lisäksi asetus `partitioned`.

```php
<?php
setcookie('sprache', 'de', [
    'expires'  => time() + 60 * 60 * 24 * 30,
    'path'     => '/',
    'secure'   => true,
    'httponly' => true,
    'samesite' => 'Lax',
]);
```

Käsikirjan mukaan arvolla `None` asetetun `samesite`-asetuksen kanssa on asetettava myös `secure`, muuten selain estää evästeen. Evästeet ovat selaimen tietoja: niiden sisältö palaa seuraavassa pyynnössä `$_COOKIE`-muuttujan kautta ja se on tarkistettava kuten mikä tahansa muu syöte. Lisää sivulla [Superglobals](https://phpsos.de/fi/php/superglobals/).

## session.upload_progress: latausten etenemisnäyttö

PHP voi kirjoittaa tiedostolatauksen aikana etenemisen istuntoon. Lomake lähettää tätä varten piilokentän, jonka nimi on asetuksesta `session.upload_progress.name`, oletuksena `PHP_SESSION_UPLOAD_PROGRESS`. PHP tallentaa tiedot sitten `$_SESSION`-muuttujaan avaimen alle, jonka etuliite on `upload_progress_`, tietoineen kuten aloitusaika, kokonaiskoko ja jo käsitellyt tavut.

Ymmärtämisen kannalta tärkeää: käsikirjan mukaan PHP kirjoittaa nämä tiedot istuntoon ennen kuin mitään komentosarjaa suoritetaan. Toiminto toimii siis pyynnön käsittelyn aikana, ennen sovelluskoodia. Sen asetusten tyyppi on `INI_PERDIR`, eikä niitä voi muuttaa ajon aikana.

## Istunnot ja PHP2Shell: väliaikaistoimi

Yhtenä väliaikaistoimena PHP2Shell-aukkoja vastaan php.net mainitsee asetuksen `session.upload_progress.enabled=0` php.ini-tiedostossa, FPM-poolissa tai palvelinkonfiguraatiossa ja kaikkien workerien uudelleenkäynnistyksen sen jälkeen, nimenomaan ei `ini_set()`-funktiolla tai `.user.ini`-tiedostolla. 23.10.2026 tuli lisäksi huomautus haavoittuvuudesta [CVE-2026-115560](https://phpsos.de/fi/php2shell/cve-2026-115560/), samalla ratkaisulla seuraavaan säännölliseen virhekorjausjulkaisuun asti.

```ini
; verkkosivuston FPM-pooli, sen jälkeen kaikkien workerien uudelleenkäynnistys
php_admin_flag[session.upload_progress.enabled] = off
```

Asiantuntijaraporttien mukaan tämä asetus yksin ei sulje molempia aukkoja. Pakollisena pysyy päivitys versioon PHP 8.5.12, 8.4.27, 8.3.36 tai 8.2.35. Käyttääkö sovelluksenne latauksen etenemistä lainkaan ja miten asetuksen saa pysyväksi, kuvaa artikkeli [session.upload_progress -toiminnon sammuttaminen](https://phpsos.de/fi/blog/session-upload-progress-abschalten/).

## Miten PHP SOS auttaa konkreettisesti?

- Luemme verkkosivustokohtaisesti todella voimassa olevat istunta-asetukset, emme pelkkiä komentorivin arvoja.
- Asetamme PHP2Shellin väliaikaistoimet poolikohtaisesti, käynnistämme kaikki workerit uudelleen ja tarkistamme tuloksen.
- Erottelemme istuntojen tallennuspaikat ja pooli-käyttäjät verkkosivustojen välillä [palvelimen koventamisen](https://phpsos.de/fi/leistungen/server-haertung/) puitteissa.
- Poikkeaman jälkeen mitätöimme kaikki olemassa olevat istunnot, jotta varastetut istuntotunnukset menettävät arvonsa.


## Usein kysytyt kysymykset

**Mikä ero on evästeellä ja istunnolla?**  
Eväste on pieni tietue, jonka selain tallentaa ja lähettää mukana jokaisessa pyynnössä. Istunto tallentaa varsinaiset tiedot palvelimelle; evästeessä on vain satunnainen tunniste, istuntotunnus.

**Kuinka kauan PHP-istunto elää?**  
Istuntoeväste on oletuksena voimassa, kunnes selain suljetaan. Palvelimella olevat tiedot saa siivota session.gc_maxlifetime-arvon jälkeen, oletuksena 1440 sekuntia ilman käyttöä. Milloin se todella tapahtuu, riippuu järjestelmän siivouslogiikasta.

**Mitä session.upload_progress tekee?**  
Toiminto kirjoittaa tiedostolatauksen aikana etenemisen istuntoon, jotta toinen pyyntö voi näyttää sen. Se on oletuksena aktiivinen. PHP2Shellin vuoksi php.net suosittelee sammuttamaan sen tilapäisesti palvelinpuolella.

**Riittääkö, että session.upload_progress sammutetaan ini_set()-funktiolla?**  
Ei. Käsikirjan mukaan asetusta ei voi muuttaa ajon aikana, ja php.net mainitsee oikeiksi paikoiksi nimenomaan php.ini-tiedoston, FPM-poolin tai palvelinkonfiguraation, ei ini_set()-funktiota eikä .user.ini-tiedostoa. Sen jälkeen kaikki workerit käynnistetään uudelleen.

## Lähteet

- [PHP-käsikirja: istuntojen konfiguraatio](https://www.php.net/manual/de/session.configuration.php)
- [PHP-käsikirja: istunnon latauksen eteneminen](https://www.php.net/manual/de/session.upload-progress.php)
- [PHP-käsikirja: setcookie](https://www.php.net/manual/en/function.setcookie.php)
- [php.net: tietoturvatiedotteet](https://www.php.net/)
