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.
; 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
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.
; 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 ú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.
-
- 23-án közlemény következett a CVE-2026-115560-ről. A lehetséges kódfuttatás ott csak a munkamenet-szerializáció, a
session_start()előttiini_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.
- 23-án közlemény következett a CVE-2026-115560-ről. A lehetséges kódfuttatás ott csak a munkamenet-szerializáció, a
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.
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 ause_trans_sid = 0ezt 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
Securejelző 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 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.