Eine PHP session ist die grundlegendste Möglichkeit, einen Benutzer über mehrere Seiten hinweg zu merken, obwohl HTTP zustandslos ist. Wenn sich jemand anmeldet, einen Artikel in den Warenkorb legt oder seine Sprachpräferenz ändert, musst du das auch beim nächsten Request wissen. Sessions und Cookies arbeiten zusammen, um das möglich zu machen. In diesem Artikel siehst du Schritt für Schritt, wie beide funktionieren, welche Einstellungen sie sicher halten und wie du dich gegen typische Angriffe wie Session-Fixation verteidigst.
Der Unterschied zwischen Session und Cookie
Beide werden oft verwechselt, doch ihre Aufgaben unterscheiden sich. Ein Cookie ist ein kleines Datenstück, das im Browser gespeichert und bei jedem Request an den Server zurückgesendet wird. Eine Session ist ein Mechanismus, bei dem die Daten auf der Serverseite liegen; der Browser hält nur eine Kennung (die Session-ID), die darauf verweist. Diese Unterscheidung ist wichtig: sensible Daten wie die E-Mail-Adresse oder die Berechtigungsstufe des Benutzers bleiben auf dem Server, und nur eine nicht erratbare ID reist zum Browser.
- Cookie: im Browser, im Klartext. Der Benutzer kann es lesen und ändern. Geeignet für nicht sensible Daten wie Sprachpräferenz oder Theme.
- Session: auf dem Server. Der Benutzer besitzt nur die ID und kann den Inhalt nicht sehen. Die richtige Wahl für Authentifizierung und sensiblen Zustand.
Eine Session starten
Eine Session beginnt immer mit session_start(). Dieser Aufruf muss erfolgen, bevor irgendeine Ausgabe gesendet wird — also vor jedem echo oder HTML — sonst erhältst du den Fehler „headers already sent". Nach dem Start liest und schreibst du Daten über das superglobale Array $_SESSION.
<?php
session_start();
// Daten schreiben
$_SESSION['user_id'] = 42;
$_SESSION['locale'] = 'de';
// Daten lesen
$userId = $_SESSION['user_id'] ?? null;
Standardmäßig werden Session-Daten in einer Datei auf dem Server gespeichert, und die Session-ID wird in einem Cookie namens PHPSESSID an den Browser gesendet. Im Hintergrund wird also bereits ein Cookie verwendet; deshalb wirken sich die Cookie-Einstellungen, die die Session-ID schützen, direkt auf deren Sicherheit aus.
Sichere Cookie-Flags
Ein großer Teil der Session-Sicherheit ergibt sich daraus, dem Session-Cookie die richtigen Flags zu geben. Du setzt diese mit session_set_cookie_params() vor dem Aufruf von session_start(). Drei Flags sind entscheidend:
<?php
session_set_cookie_params([
'lifetime' => 0, // endet beim Schließen des Browsers
'path' => '/',
'secure' => true, // nur über HTTPS
'httponly' => true, // für JavaScript nicht erreichbar
'samesite' => 'Lax', // Schutz gegen CSRF
]);
session_start();
- Secure: Das Cookie wird nur über eine HTTPS-Verbindung gesendet. Das verhindert, dass die Session-ID über unverschlüsseltes HTTP gestohlen wird.
- HttpOnly: Das Cookie ist aus JavaScript über
document.cookienicht erreichbar. Selbst wenn eine XSS-Lücke besteht, erschwert das den Diebstahl der Session-ID erheblich. - SameSite: Steuert, ob das Cookie bei Requests von anderen Seiten gesendet wird.
Laxist für die meisten Anwendungen eine gute Balance;Strictist restriktiver.
Schutz vor Session-Fixation
Ein Session-Fixation-Angriff funktioniert, indem das Opfer dazu gebracht wird, eine Session-ID zu verwenden, die der Angreifer bereits kennt. Wenn sich das Opfer mit dieser ID anmeldet, schlüpft der Angreifer mit derselben ID in die Session. Die Lösung ist einfach, aber entscheidend: erneuere die Session-ID immer dann, wenn sich die Berechtigungsstufe ändert. Mit anderen Worten: rufe session_regenerate_id() in dem Moment auf, in dem sich der Benutzer anmeldet.
<?php
// NACH der Überprüfung des Passworts
if (password_verify($password, $hash)) {
// Alte Session ungültig machen, neue ID erzeugen
session_regenerate_id(true);
$_SESSION['user_id'] = $user['id'];
$_SESSION['logged_in'] = true;
}
Das Argument true löscht hier auch die alte Session-Datei. Dasselbe Prinzip gilt bei einer Rechteerhöhung, etwa wenn ein normaler Benutzer in ein Admin-Panel wechselt.
Eine Session sicher beenden
Das Abmelden ist nicht erledigt, indem man nur $_SESSION leert. Du musst sowohl die Daten auf dem Server als auch das Cookie im Browser bereinigen. Ein vollständiges Logout sieht so aus:
<?php
session_start();
// 1. Session-Daten leeren
$_SESSION = [];
// 2. Session-Cookie löschen
if (ini_get('session.use_cookies')) {
$params = session_get_cookie_params();
setcookie(
session_name(), '', time() - 42000,
$params['path'], $params['domain'],
$params['secure'], $params['httponly']
);
}
// 3. Session auf dem Server zerstören
session_destroy();
Einen dieser drei Schritte auszulassen ist ein häufiger Fehler: Rufst du nur session_destroy() auf, kann ein veraltetes Cookie im Browser zurückbleiben; machst du nur $_SESSION = [], wird die Datei auf dem Server nicht entfernt.
Eigene Cookies richtig verwenden
Über Sessions hinaus kannst du Cookies auch direkt für nicht sensible Daten wie eine Sprach- oder Theme-Präferenz verwenden. Ab PHP 7.3 unterstützt setcookie(), die Optionen als Array zu übergeben, womit du moderne Flags wie SameSite sauber definieren kannst:
<?php
setcookie('theme', 'dark', [
'expires' => time() + 60 * 60 * 24 * 30, // 30 Tage
'path' => '/',
'secure' => true,
'httponly' => false, // falls JS es lesen muss
'samesite' => 'Lax',
]);
Denk daran: Daten, die du in ein Cookie schreibst, können vom Benutzer geändert werden. Stütze daher niemals eine Vertrauensentscheidung wie „ist dieser Benutzer ein Admin?" auf einen Cookie-Wert. Autorisierungsentscheidungen müssen sich immer auf die serverseitige Session stützen.
Häufige Fragen
Wo werden Session-Daten gespeichert?
Standardmäßig als Datei in einem temporären Ordner auf dem Server. Die Einstellung session.save_path legt diesen Speicherort fest. In Anwendungen, die horizontal skalieren, ist es üblich, auf einen Session-Treiber auf Basis von Redis oder einer Datenbank umzusteigen, damit mehrere Server dieselbe Session sehen.
Wie lange lebt eine Session?
Zwei Einstellungen beeinflussen das: session.gc_maxlifetime entscheidet, wie lange die Daten auf dem Server gültig bleiben, während die lifetime des Cookies entscheidet, wie lange der Browser die Session-ID behält. Wenn du ein echtes „nach X abmelden"-Timeout willst, ist der zuverlässigste Weg, den Zeitpunkt der letzten Aktivität in der Session zu speichern und ihn selbst zu prüfen.
Darf ich sensible Daten in einem Cookie speichern?
Nein. Ein Cookie liegt im Klartext im Browser und kann vom Benutzer gelesen und geändert werden. Dinge wie Passwörter oder Berechtigungsstufen müssen in der serverseitigen Session bleiben; ein Cookie sollte nur die nicht erratbare Session-ID oder nicht sensible Präferenzen tragen.
Richte die Session-Verwaltung von Anfang an korrekt ein. Wenn du die Authentifizierung in einem bestehenden PHP-Projekt absichern oder eine solide Session-Schicht von Grund auf aufbauen möchtest, nimm Kontakt mit mir auf, und lass uns gemeinsam ein sicheres Fundament legen.