# Munkamenetek védelme PHP-ban: a PHP-munkamenet biztonsága a gyakorlatban

> PHP-munkamenet biztonsága lépésről lépésre: biztonságos php.ini-értékek, új session-azonosító bejelentkezés után, cookie-jelzők, PHP2Shell upload progress.

Forrás: https://phpsos.de/hu/ratgeber/session-sicherheit-php/  
Állapot: 2026. 10. 25.  
Szolgáltató: PHP SOS, PHP-vészhelyzeti segítség és szerverbiztonság. Azonnali segítség WhatsAppon: https://wa.me/491736494914?text=%C3%9Cdv%C3%B6zl%C3%B6m%2C%20PHP%20SOS%21%20Seg%C3%ADts%C3%A9gre%20van%20sz%C3%BCks%C3%A9g%C3%BCnk%20a%20PHP-szerver%C3%BCnkkel.%20C%C3%A9g%3A%20%E2%80%A6%20Weboldal%3A%20%E2%80%A6

**Röviden:** A PHP-munkamenet biztonságában négy dolog számít: biztonságos cookie-beállítások, új session-azonosító minden bejelentkezés után, elkülönített és védett tárolási helyek, valamint rövid érvényességi idők. A PHP2Shell miatt ezen felül a `session.upload_progress.enabled=0` értéket szerveroldalon be kell állítani, amíg nincs ok erre a funkcióra.

## Miért értékes célpontok a munkamenetek

Egy munkamenet megjegyzi, hogy egy felhasználó be van jelentkezve. Technikailag a böngésző ehhez egy véletlenszerű session-azonosítót kap egy cookie-ban, a szerver pedig eltárolja a hozzá tartozó adatokat. Aki ismeri ezt az azonosítót, az az alkalmazás számára ugyanaz a felhasználó, jelszó és második faktor nélkül.

Az üzemeltetők számára ez azt jelenti: egy gyenge munkamenet-kezelés kijátszhatja a bejelentkezés védelmét, még ha a jelszavak és a kétfaktoros bejelentkezés szabályosan meg is vannak valósítva. Különösen kritikus ez az admin területeknél, az ügyfélfiókoknál és a személyes adatokat kezelő portáloknál.

A tipikus kockázatok: a session-azonosító elfogása (session hijacking), egy ismert azonosító alátolása a bejelentkezés előtt (session fixation), és a megosztott gépeken túl hosszan érvényes munkamenetek.

## Biztonságos alapbeállítások a php.ini-ben

A legfontosabb értékek központilag a `php.ini`-ben vagy weboldalanként az FPM-poolban állíthatók be. A poolban használja a `php_admin_value` vagy `php_admin_flag` direktívát, hogy az alkalmazás ne tudja felülírni az értékeket.

```ini
; A munkamenetek alapkeményítése
session.use_strict_mode   = 1
session.use_only_cookies  = 1
session.use_trans_sid     = 0
session.cookie_httponly   = 1
session.cookie_secure     = 1
session.cookie_samesite   = "Lax"
session.cookie_lifetime   = 0
session.gc_maxlifetime    = 1800
session.name              = "APPSESSID"

; PHP2Shell-figyelmeztetés a php.net-től, utána indítsa újra az összes workert
session.upload_progress.enabled = 0
```

A `use_strict_mode` gondoskodik arról, hogy a PHP ne vegyen át a böngésző által megadott, ismeretlen azonosítókat. A `cookie_httponly` megakadályozza, hogy a JavaScript elolvassa az azonosítót, ami korlátozza a Cross-Site Scripting következményeit. A `cookie_secure` a cookie-t csak HTTPS-en küldi. A `SameSite=Lax` megnehezíti a Cross-Site kéréseket érvényes munkamenettel; tisztán admin területeknél a `Strict` is megfelelő lehet.

Az 1800 másodperces érvényességi idő példaérték. Állítsa be a védelmi igény szerint: rövidebbre az adminisztrációnál és az ügyféladatoknál, hosszabbra csak ott, ahol szakmailag szükséges.

Vegye figyelembe, hogy a `gc_maxlifetime` csak azt rögzíti, mikortól törölhetők a régi session-adatok. Egyes disztribúciókon nem maga a PHP, hanem egy rendszeres rendszerfeladat takarítja a session-fájlokat. Ilyenkor ellenőrizze, hogy ez a feladat milyen értéket használ, hogy az Ön beállítása ténylegesen érvényesüljön. Az inaktivitás utáni kijelentkeztetésnél emellett ne támaszkodjon kizárólag a takarító funkcióra, hanem az utolsó művelet időpontját magában az alkalmazásban ellenőrizze, ahogy a következő példa mutatja.

## A session-azonosító megújítása bejelentkezés után

A kódban a legfontosabb szabály, hogy a session-azonosítót minden jogosultságváltásnál újra létrehozza, tehát bejelentkezéskor, admin módba váltáskor és kijelentkezéskor. A következő példa egy tiszta alapmintát mutat a `password_verify()`-val:

```php
<?php
declare(strict_types=1);

session_start();

function anmelden(PDO $db, string $email, string $passwort): bool
{
    $stmt = $db->prepare('SELECT id, passwort_hash FROM benutzer WHERE email = :email');
    $stmt->execute(['email' => $email]);
    $nutzer = $stmt->fetch(PDO::FETCH_ASSOC);

    if (!$nutzer || !password_verify($passwort, $nutzer['passwort_hash'])) {
        return false; // ugyanaz az üzenet hibás címre és hibás jelszóra
    }

    session_regenerate_id(true);           // új azonosító, a régi elvetése
    $_SESSION['benutzer_id']   = (int) $nutzer['id'];
    $_SESSION['letzte_aktion'] = time();
    return true;
}

function pruefeLeerlauf(int $sekunden = 900): void
{
    if (isset($_SESSION['letzte_aktion']) && time() - $_SESSION['letzte_aktion'] > $sekunden) {
        abmelden();
        return;
    }
    $_SESSION['letzte_aktion'] = time();
}

function abmelden(): void
{
    $_SESSION = [];
    $p = session_get_cookie_params();
    setcookie(session_name(), '', [
        'expires'  => time() - 3600,
        'path'     => $p['path'],
        'domain'   => $p['domain'],
        'secure'   => $p['secure'],
        'httponly' => $p['httponly'],
        'samesite' => $p['samesite'],
    ]);
    session_destroy();
}
```

Kiegészítésként védje a valamit módosító űrlapokat CSRF-tokennel. Ezt a `bin2hex(random_bytes(32))` hozza létre, a munkamenetben tárolják, és elküldéskor a `hash_equals()`-szal hasonlítják össze.

## Tárolási helyek és az ügyfelek elkülönítése

A PHP alapértelmezetten fájlokként, egy közös könyvtárban tárolja a munkameneteket. Több weboldalt kiszolgáló szerveren ez azt jelentheti, hogy egy feltört weboldal el tudja olvasni egy másik munkameneteit. Ezért minden weboldalhoz saját pool tartozik saját felhasználóval és saját session-útvonallal.

```ini
; az adott weboldal FPM-poolában
php_admin_value[session.save_path] = /var/lib/php/sessions/kunde-a
```

A könyvtárnak a pool felhasználójához kell tartoznia, és `0700` jogokkal kell rendelkeznie. Hogyan zárhatja el a weboldalakat egymástól még tovább, azt az [open_basedir és weboldalankénti elkülönítés](https://phpsos.de/hu/ratgeber/open-basedir/) útmutató írja le. Ha a munkameneteket Redisben vagy adatbázisban tárolják, ugyanazok az alapelvek érvényesek: alkalmazásonként saját hozzáférés, nincs nyitott hálózati hozzáférés.

## A PHP-munkamenet biztonsága és a PHP2Shell

A PHP2Shell rések, a CVE-2026-109618 és a CVE-2026-109619, magában a PHP-ban vannak. Az egyik átmeneti intézkedésként a php.net azt nevezi meg, hogy a `session.upload_progress.enabled=0` értéket a php.ini-ben, az FPM-poolban vagy a szerverkonfigurációban kell beállítani, majd az összes workert újra kell indítani. Kifejezetten nem `ini_set()`-tel vagy `.user.ini`-vel.

2026. 10. 23-án közlemény következett a [CVE-2026-115560](https://phpsos.de/hu/php2shell/cve-2026-115560/)-ről. A lehetséges kódfuttatás ott csak a munkamenet-szerializáció, a `session_start()` előtti `ini_set()`-es átállítás és az aktív upload progress szokatlan kombinációja esetén áll fenn. A megoldás ugyanez a beállítás, a következő rendes hibajavító kiadásig.

> **Fontos:**
> Ez a beállítás átmeneti intézkedés, és nem teljes védelem. Döntő marad a javított PHP-verzióra való frissítés és az azt követő [az összes PHP-worker újraindítása](https://phpsos.de/hu/php2shell/php-fpm-neustart/).

A módosítás után ellenőrizze, hogy ténylegesen melyik érték érvényes. A parancssor gyakran más konfigurációt mutat, mint a webszerver; megbízható egy védett, majd ismét törölt ellenőrző oldal vagy maga a pool-konfiguráció.

## Tipikus hibák a PHP-alkalmazások munkameneteinél

Sok sebezhetőség nem a hiányzó beállításokból, hanem abból ered, ahogyan az alkalmazások a munkameneteket használják. Ezekre a mintákra célzottan kérdezzen rá a saját kódjában és a szolgáltatóinál:

- **Túl sok a munkamenetben:** Jelszavak, teljes fizetési adatok vagy nagy adathalmazok nem valók a munkamenetbe. Csak azt tárolja, ami a hozzárendeléshez szükséges, például a felhasználói azonosítót és a szerepköröket.
- **Jogok csak a munkamenetből:** Hogy ki rendszergazda, azt kritikus műveleteknél az adatbázissal szemben kell ellenőrizni. Különben a megvont jogok a munkamenet lejártáig érvényben maradnak.
- **Session-azonosító a címben:** Az URL-ekben lévő azonosítók naplókba, böngészési előzményekbe és Referer-adatokba kerülnek. A `use_only_cookies` és a `use_trans_sid = 0` ezt megakadályozza.
- **Nincs vége a munkamenetnek:** Ha hiányzik a tétlenségi időkorlát, egy rendszergazda egy megosztott gépen korlátlanul bejelentkezve marad.
- **A HTTPS rossz felismerése proxy mögött:** Ha a titkosítás a load balancernél ér véget, az alkalmazásnak tudnia kell erről. Különben a cookie-kat esetleg `Secure` jelző nélkül állítja be.

Egy biztonsági incidens után ahhoz is hozzátartozik, hogy az összes meglévő munkamenetet el kell vetni. Ez a legegyszerűbben úgy történik, hogy törli a session-könyvtár tartalmát, vagy megváltoztatja a session nevét. Minden felhasználónak ekkor újra be kell jelentkeznie, és az ellopott munkamenetek értéktelenné válnak.

## Hogyan segít konkrétan a PHP SOS?

- Ellenőrizzük a munkamenet-beállításokat, a cookie-jelzőket és a tárolási helyeket egy szerver összes weboldalán, és dokumentáljuk a ténylegesen érvényes értékeket.
- Poolonként bevezetjük a PHP2Shell átmeneti intézkedéseit, ellenőrzötten újraindítjuk a workereket, és igazoljuk az eredményt.
- A [szerver-keményítés](https://phpsos.de/hu/leistungen/server-haertung/) keretében a weboldalakat saját poolokkal és session-útvonalakkal választjuk el.
- Saját fejlesztéseknél ellenőrizzük a bejelentkezést, a kijelentkezést és a session-váltást a kódban, és konkrét módosításokat javasolunk.


## Gyakori kérdések

**Mi az a session hijacking?**  
Session hijackingnél a támadó átveszi egy bejelentkezett felhasználó munkamenetét azáltal, hogy megszerzi a session-azonosítóját. Az azonosítóval az alkalmazás számára ő ez a felhasználó, anélkül hogy ismerné a jelszót. A biztonságos cookie-jelzők és a rövid érvényességi idők ezt jelentősen megnehezítik.

**Miért kell bejelentkezés után új session-azonosítót létrehozni?**  
Ha az azonosító a bejelentkezés előtt és után ugyanaz, egy korábban ismert vagy alátolt azonosító a bejelentkezés után is érvényes maradhatna. A session_regenerate_id(true) új azonosítót hoz létre, és elveti a régit.

**Kikapcsolhatom a session.upload_progress.enabled-t ini_set()-tel?**  
Nem, a php.net szerint ez nem elég. A beállítás a php.ini-be, az FPM-poolba vagy a szerverkonfigurációba tartozik, nem az ini_set()-be vagy egy .user.ini-be. Ezután az összes PHP-workert újra kell indítani.

**Hol érdemes tárolni a session-fájlokat?**  
A webgyökéren kívüli könyvtárban, amelyet csak az adott PHP-pool felhasználója olvashat. Több weboldalt kiszolgáló szervereken minden weboldalnak saját session-könyvtára legyen.

## Források

- [OWASP Cheat Sheet Series (Session Management)](https://cheatsheetseries.owasp.org/)
- [php.net: biztonsági közlemények a PHP2Shellről](https://www.php.net/)
- [PHP 8 ChangeLog](https://www.php.net/ChangeLog-8.php)
