# Sessions und Cookies in PHP

> Wie PHP-Sessions und Cookies funktionieren: Session-ID, Speicherung, Standardwerte der php.ini, Upload-Fortschritt und die PHP2Shell-Übergangsmaßnahme.

Quelle: https://phpsos.de/php/sessions-und-cookies/  
Stand: 25.10.2026  
Anbieter: PHP SOS, PHP-Notfallhilfe und Server-Sicherheit. Soforthilfe per WhatsApp: https://wa.me/491736494914?text=Hallo%20PHP%20SOS%2C%20wir%20brauchen%20Hilfe%20mit%20unserem%20PHP-Server.%20Firma%3A%20%E2%80%A6%20Website%3A%20%E2%80%A6

**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:

1. Der Browser schickt das Cookie mit dem Session-Namen mit, standardmäßig `PHPSESSID`.
2. `session_start()` liest die ID und übergibt sie dem Speicher-Handler, standardmäßig `files`.
3. Der Handler lädt die gespeicherten Daten, PHP wandelt sie mit dem `serialize_handler` zurück und füllt `$_SESSION`.
4. Das Skript liest und ändert `$_SESSION` wie ein normales Array.
5. 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
<?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](https://phpsos.de/ratgeber/session-sicherheit-php/). 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
<?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](https://phpsos.de/php/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](https://phpsos.de/php2shell/cve-2026-115560/) hinzu, mit derselben Abhilfe bis zum nächsten regulären Bugfix-Release.

```ini
; 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](https://phpsos.de/blog/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](https://phpsos.de/leistungen/server-haertung/).
- 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.

## Quellen

- [PHP-Handbuch: Session-Konfiguration](https://www.php.net/manual/de/session.configuration.php)
- [PHP-Handbuch: Session-Upload-Fortschritt](https://www.php.net/manual/de/session.upload-progress.php)
- [PHP-Handbuch: setcookie](https://www.php.net/manual/en/function.setcookie.php)
- [php.net: Sicherheitsmeldungen](https://www.php.net/)
