Kurz gesagt: HTTP merkt sich zwischen zwei Anfragen nichts. Eine PHP-Session löst das: PHP vergibt eine zufällige Session-ID, schickt sie als Cookie an den Browser und speichert die zugehörigen Daten auf dem Server, standardmäßig als Datei. Bei jeder weiteren Anfrage liest session_start() die Daten anhand der ID wieder ein. Zur PHP-Session gehört auch die Funktion session.upload_progress, die php.net wegen PHP2Shell vorübergehend serverseitig abzuschalten empfiehlt.
Warum Webanwendungen Sessions brauchen
Jede Anfrage an einen Webserver steht für sich. Ohne Zusatzmechanismus wüsste ein Shop beim Klick auf „Warenkorb“ nicht mehr, wer eben etwas hineingelegt hat, und ein Admin-Bereich müsste bei jedem Klick das Passwort abfragen. Sessions verbinden einzelne Anfragen zu einer Sitzung.
Für Entscheider heißt das: Die Session-ID ist nach dem Login so viel wert wie Benutzername und Passwort zusammen. Für Admins heißt das: Wo und wie Session-Daten liegen, ist eine Sicherheitsfrage, besonders auf Servern mit mehreren Websites.
Was bei session_start() passiert
Der Ablauf ist bei jeder Anfrage gleich und lässt sich in fünf Schritten beschreiben:
- Der Browser schickt das Cookie mit dem Session-Namen mit, standardmäßig
PHPSESSID. session_start()liest die ID und übergibt sie dem Speicher-Handler, standardmäßigfiles.- Der Handler lädt die gespeicherten Daten, PHP wandelt sie mit dem
serialize_handlerzurück und füllt$_SESSION. - Das Skript liest und ändert
$_SESSIONwie ein normales Array. - Am Ende der Anfrage schreibt PHP die Daten zurück. Mit
session.lazy_write(Standard: an) nur dann, wenn sie sich geändert haben.
<?php
session_start();
$_SESSION['besuche'] = ($_SESSION['besuche'] ?? 0) + 1;
echo 'Seitenaufrufe in dieser Sitzung: ', (int) $_SESSION['besuche'];
Gibt es noch keine Session, erzeugt PHP eine neue ID und setzt das Cookie. Ist session.use_strict_mode aktiv, lehnt PHP vom Browser vorgegebene, unbekannte IDs ab und erzeugt eine neue. Das PHP-Handbuch bezeichnet diese Einstellung für die grundlegende Sicherheit als zwingend.
Standardwerte, die man kennen sollte
Die folgenden Werte gelten laut PHP-Handbuch, wenn nichts anderes konfiguriert ist. Viele Distributionen und Hoster setzen eigene Werte, deshalb zählt immer die tatsächlich wirksame Konfiguration.
| Einstellung | Standard | Bedeutung |
|---|---|---|
session.save_handler |
files |
Speicherort der Daten, auch Redis oder Datenbank möglich |
session.name |
PHPSESSID |
Name des Cookies |
session.serialize_handler |
php |
Format der gespeicherten Daten |
session.use_strict_mode |
0 |
unbekannte IDs werden übernommen |
session.use_only_cookies |
1 |
keine Session-ID in der Adresse |
session.cookie_httponly |
0 |
JavaScript kann das Cookie lesen |
session.cookie_secure |
0 |
Cookie auch über unverschlüsseltes HTTP |
session.cookie_samesite |
leer | kein SameSite-Attribut |
session.gc_maxlifetime |
1440 |
Sekunden bis zum möglichen Aufräumen |
session.gc_probability / gc_divisor |
1 / 100 |
Aufräumen bei etwa jedem hundertsten Start |
session.upload_progress.enabled |
1 |
Upload-Fortschritt wird in die Session geschrieben |
Die Werte für cookie_httponly, cookie_secure und use_strict_mode sind ab Werk also nicht auf Sicherheit ausgelegt. Wie Sie sie richtig setzen, beschreibt der Ratgeber Sessions in PHP absichern. Die Einstellungen session.sid_length und session.sid_bits_per_character sind seit PHP 8.4.0 als veraltet markiert.
Cookies direkt setzen
Neben dem Session-Cookie kann eine Anwendung eigene Cookies setzen. Seit PHP 7.3.0 nimmt setcookie() dafür ein Array mit Optionen an, einschließlich samesite. Seit PHP 8.5.0 gibt es zusätzlich die Option partitioned.
<?php
setcookie('sprache', 'de', [
'expires' => time() + 60 * 60 * 24 * 30,
'path' => '/',
'secure' => true,
'httponly' => true,
'samesite' => 'Lax',
]);
Laut Handbuch muss bei samesite gleich None auch secure gesetzt sein, sonst blockiert der Browser das Cookie. Cookies sind Daten des Browsers: Ihr Inhalt kommt bei der nächsten Anfrage über $_COOKIE zurück und muss wie jede andere Eingabe geprüft werden. Mehr dazu auf der Seite Superglobals.
session.upload_progress: Fortschrittsanzeige für Uploads
PHP kann während eines Datei-Uploads den Fortschritt in die Session schreiben. Dazu schickt das Formular ein verstecktes Feld mit dem Namen aus session.upload_progress.name, standardmäßig PHP_SESSION_UPLOAD_PROGRESS. PHP legt die Daten dann unter einem Schlüssel mit dem Präfix upload_progress_ in $_SESSION ab, mit Angaben wie Startzeit, Gesamtgröße und bereits verarbeiteten Bytes.
Wichtig für das Verständnis: Laut Handbuch schreibt PHP diese Informationen in die Session, bevor irgendein Skript ausgeführt wird. Die Funktion arbeitet also während der Verarbeitung der Anfrage, noch vor dem Anwendungscode. Ihre Einstellungen sind vom Typ INI_PERDIR und lassen sich nicht zur Laufzeit ändern.
Sessions und PHP2Shell: die Übergangsmaßnahme
Als eine der Übergangsmaßnahmen gegen die PHP2Shell-Lücken nennt php.net, session.upload_progress.enabled=0 in der php.ini, im FPM-Pool oder in der Serverkonfiguration zu setzen und danach alle Worker neu zu starten, ausdrücklich nicht über ini_set() oder .user.ini. Am 23.10.2026 kam der Hinweis zu CVE-2026-115560 hinzu, mit derselben Abhilfe bis zum nächsten regulären Bugfix-Release.
; FPM-Pool der Website, danach alle Worker neu starten
php_admin_flag[session.upload_progress.enabled] = off
Laut Fachberichten schließt diese Einstellung allein nicht beide Lücken. Pflicht bleibt das Update auf PHP 8.5.12, 8.4.27, 8.3.36 oder 8.2.35. Ob Ihre Anwendung den Upload-Fortschritt überhaupt nutzt und wie Sie die Einstellung dauerhaft setzen, beschreibt der Beitrag session.upload_progress abschalten.
Wie hilft PHP SOS konkret?
- Wir lesen die tatsächlich wirksamen Session-Einstellungen je Website aus, nicht nur die Werte der Kommandozeile.
- Wir setzen die PHP2Shell-Übergangsmaßnahmen pro Pool, starten alle Worker neu und prüfen das Ergebnis.
- Wir trennen Session-Speicherorte und Pool-Benutzer zwischen Websites im Rahmen der Server-Härtung.
- Nach einem Vorfall verwerfen wir alle bestehenden Sitzungen, damit gestohlene Session-IDs wertlos werden.
Häufige Fragen
Was ist der Unterschied zwischen Cookie und Session?
Ein Cookie ist ein kleiner Datensatz, den der Browser speichert und bei jeder Anfrage mitschickt. Eine Session speichert die eigentlichen Daten auf dem Server; im Cookie steht nur eine zufällige Kennung, die Session-ID.
Wie lange lebt eine PHP-Session?
Das Session-Cookie gilt standardmäßig, bis der Browser geschlossen wird. Die Daten auf dem Server dürfen nach session.gc_maxlifetime, standardmäßig 1440 Sekunden ohne Zugriff, aufgeräumt werden. Wann das tatsächlich passiert, hängt von der Aufräumlogik des Systems ab.
Was macht session.upload_progress?
Die Funktion schreibt während eines Datei-Uploads den Fortschritt in die Session, damit eine zweite Anfrage ihn anzeigen kann. Sie ist standardmäßig aktiv. Wegen PHP2Shell empfiehlt php.net, sie vorübergehend serverseitig abzuschalten.
Reicht es, session.upload_progress per ini_set() abzuschalten?
Nein. Die Einstellung lässt sich laut Handbuch ohnehin nicht zur Laufzeit ändern, und php.net nennt ausdrücklich php.ini, FPM-Pool oder Serverkonfiguration als richtige Orte, nicht ini_set() oder .user.ini. Danach alle Worker neu starten.