in Symfony, der vollständige Guide
Eine bequeme Remember-Me-Funktion und eine sichere Session schließen sich nicht aus, wenn man die richtigen Bausteine kennt. Dieser Guide zeigt persistente Remember-Me-Tokens statt unsicherer signierter Cookies, Schutz vor Session-Fixation und eine Timeout-Strategie, die zur tatsächlichen Sensitivität der Anwendung passt.
Inhaltsverzeichnis
- 1. Warum Remember Me und Session Sicherheit zusammengehören
- 2. Das Problem mit signierten Cookie-Tokens
- 3. Persistente Tokens: das sichere Remember-Me-Muster
- 4. Persistentes Remember Me in Symfony einrichten
- 5. Session-Fixation verhindern
- 6. Timeout-Strategien: Idle, Absolute und Remember-Me-Dauer
- 7. Logout, der wirklich alles beendet
- 8. Geräteübersicht und gezielter Widerruf
- 9. Remember-Me-Strategien im Vergleich
- 10. Zusammenfassung
- 11. FAQ
1. Warum Remember Me und Session Sicherheit zusammengehören
Eine Remember Me-Funktion verlängert die Anmeldung eines Benutzers über das Ende der Browser-Session hinaus, oft um Wochen oder Monate. Genau diese Langlebigkeit macht sie zu einem der sensibelsten Bausteine der gesamten Session Sicherheit einer Anwendung: ein gestohlenes Remember-Me-Cookie ist potenziell viel länger nutzbar als ein normales Session-Cookie, das nach wenigen Stunden Inaktivität abläuft.
Wer Remember Me ohne Rücksicht auf die zugrunde liegende Session-Architektur implementiert, überträgt oft unbewusst dieselben Schwächen wie bei normalen Sessions, nur mit einer viel größeren Zeitspanne, in der ein Angriff wirksam bleibt. Dieser Guide behandelt deshalb beide Themen zusammen: sichere Remember-Me-Tokens und robuste Session-Sicherheit als zwei Seiten derselben Medaille, nicht als getrennte Features.
2. Das Problem mit signierten Cookie-Tokens
Symfonys einfachster Remember Me-Modus, der signierte Cookie-Token, kodiert Benutzername, Ablaufzeit und eine Signatur direkt in ein Cookie, ganz ohne Datenbank-Backend. Das ist simpel einzurichten, hat aber einen entscheidenden Nachteil: es gibt keine Möglichkeit, ein einzelnes ausgestelltes Cookie zu widerrufen, ohne das geheime Signing-Secret der gesamten Anwendung zu rotieren und damit alle ausgestellten Remember-Me-Cookies aller Benutzer gleichzeitig zu invalidieren.
Für Session Sicherheit in ernsthaften Produktionsumgebungen ist das ein Dealbreaker. Wird ein Laptop mit einem gültigen signierten Remember-Me-Cookie gestohlen, bleibt dieses Cookie bis zu seinem eingebauten Ablaufdatum gültig, es gibt keinen Weg, gezielt genau dieses eine Cookie zu deaktivieren, während alle anderen Benutzer weiterhin angemeldet bleiben. Diese Unfähigkeit zum gezielten Widerruf ist der zentrale Grund, warum das persistente Token-Muster in Produktion die bessere Wahl ist.
3. Persistente Tokens: das sichere Remember-Me-Muster
Symfonys PersistentTokenBasedRememberMeHandler speichert für jedes ausgestellte Remember Me-Cookie einen Datenbank-Eintrag mit Benutzer-Identifier, einem Serien-Identifier und einem gehashten, rotierenden Token-Wert. Bei jeder Verwendung des Remember-Me-Cookies wird der Token-Wert in der Datenbank durch einen neuen ersetzt, ein Muster, das man Token-Rotation nennt. Dadurch wird ein bereits benutztes, altes Token automatisch ungültig, selbst wenn der zugehörige Serien-Identifier weiterverwendet wird.
Diese Rotation hat einen entscheidenden Sicherheitsvorteil: wird ein altes, bereits durch Rotation ersetztes Token dennoch erneut präsentiert, ein starkes Indiz für Diebstahl, kann die Anwendung sofort die gesamte Serie widerrufen und den Benutzer aktiv informieren, statt das gestohlene Cookie einfach nur abzulehnen. Für echte Session Sicherheit in Produktion ist dieser Diebstahl-Erkennungsmechanismus ein wesentlicher Vorteil gegenüber dem einfachen signierten Cookie-Modus.
# config/packages/security.yaml
security:
firewalls:
main:
remember_me:
secret: '%kernel.secret%'
# Persistent tokens — not signed cookies — enable per-device revocation
token_provider:
doctrine: true
lifetime: 2592000 # 30 days
path: /
# Require a fresh login for sensitive actions even with a valid remember-me cookie
always_remember_me: false
remember_me_parameter: _remember_me
4. Persistentes Remember Me in Symfony einrichten
Die Doctrine-basierte Token-Speicherung benötigt eine Tabelle mit den Spalten series, value, class, username und last_used. Symfony liefert dafür ein fertiges Schema, das über bin/console doctrine:schema:update oder eine Migration angelegt wird. Wichtig: die value-Spalte speichert nicht den Klartext-Token, sondern einen Hash, exakt nach demselben Prinzip wie bei sicherer API Token Authentifizierung, ein Datenbank-Leak macht die Tokens also nicht direkt nutzbar.
Nach der Einrichtung erscheint ein zusätzliches Cookie im Browser, unabhängig vom eigentlichen Session-Cookie. Dieses Remember-Me-Cookie enthält ausschließlich den Serien-Identifier und den aktuellen Token-Wert, niemals das Passwort oder einen anderen sensiblen Wert im Klartext. Bei jedem Seitenaufruf ohne aktive Session prüft ein eigener Remember Me-Listener dieses Cookie und stellt bei Erfolg automatisch eine neue authentifizierte Session her, ohne dass der Benutzer sein Passwort erneut eingeben muss.
5. Session-Fixation verhindern
Session-Fixation ist ein Angriff, bei dem ein Angreifer einem Opfer eine bereits bekannte Session-ID unterschiebt, etwa über einen manipulierten Link, und darauf wartet, dass sich das Opfer mit dieser ID anmeldet. Gelingt das, kennt der Angreifer nach dem Login des Opfers dieselbe, nun authentifizierte Session-ID. Symfony schützt standardmäßig dagegen, indem bei jedem erfolgreichen Login automatisch eine komplett neue Session-ID generiert wird, ein Verhalten, das niemals deaktiviert werden sollte, auch nicht aus vermeintlichen Performance-Gründen.
Für Session Sicherheit reicht die Session-ID-Regenerierung beim Login allein nicht immer aus. Bei Anwendungen mit besonders sensiblen Berechtigungsänderungen, etwa dem Wechsel von einem normalen Benutzerkonto zu einem Administrator-Kontext, sollte die Session-ID auch bei jeder signifikanten Rechteänderung neu generiert werden. Symfonys Security::login() und die entsprechenden Authenticator-Hooks übernehmen diese Regenerierung automatisch, ein manuell gebauter Login-Mechanismus außerhalb des Security-Systems muss das explizit selbst implementieren.
<?php
declare(strict_types=1);
namespace App\EventListener;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Security\Http\Event\LoginSuccessEvent;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
#[AsEventListener(event: LoginSuccessEvent::class)]
final class SessionRegenerationListener
{
public function __invoke(LoginSuccessEvent $event): void
{
$session = $event->getRequest()->getSession();
// Symfony already regenerates the session id on login by default —
// this listener is only needed for additional privilege-escalation points
if ($session instanceof SessionInterface) {
$session->migrate(true); // true: destroy the old session data on the server too
}
}
}
6. Timeout-Strategien: Idle, Absolute und Remember-Me-Dauer
Drei unabhängige Zeitgrenzen bestimmen zusammen die tatsächliche Session Sicherheit einer Anwendung. Der Idle-Timeout, konfiguriert über gc_maxlifetime in php.ini oder in Symfonys Session-Konfiguration, beendet eine Session nach einer bestimmten Zeit ohne Aktivität. Ein Absolute-Timeout, in Symfony nicht eingebaut, sondern über einen eigenen Listener realisiert, beendet eine Session nach einer festen Höchstdauer, unabhängig von fortlaufender Aktivität, und schützt so vor dauerhaft offenen Sessions in vergessenen Browser-Tabs.
Die dritte Zeitgrenze ist die Remember Me-Lebensdauer selbst, oft deutlich länger als beide Session-Timeouts, weil sie ein bewusst gewähltes Komfort-Feature ist, kein Sicherheitsmechanismus. Für sensible Bereiche einer Anwendung, etwa Zahlungseinstellungen oder Administrationsfunktionen, sollte ein gültiges Remember-Me-Cookie allein nicht ausreichen. Das always_remember_me-Flag auf false zu belassen und stattdessen für kritische Aktionen eine erneute Passwort-Eingabe zu verlangen, kombiniert Komfort für alltägliche Nutzung mit echter Absicherung für kritische Operationen.
<?php
declare(strict_types=1);
namespace App\EventListener;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
/**
* Absolute session timeout — Symfony has no built-in equivalent,
* gc_maxlifetime only covers the idle timeout.
*/
#[AsEventListener(event: 'kernel.request', priority: 8)]
final class AbsoluteSessionTimeoutListener
{
private const int MAX_SESSION_LIFETIME = 28800; // 8 hours, regardless of activity
public function __invoke(RequestEvent $event): void
{
$session = $event->getRequest()->getSession();
if (!$session->isStarted()) {
return;
}
$createdAt = $session->get('_session_created_at');
if ($createdAt === null) {
$session->set('_session_created_at', time());
return;
}
if (time() - $createdAt > self::MAX_SESSION_LIFETIME) {
$session->invalidate();
}
}
}
7. Logout, der wirklich alles beendet
Ein unvollständiger Logout ist eine der häufigsten Lücken in der Session Sicherheit vieler Anwendungen: die aktuelle PHP-Session wird beendet, aber das Remember-Me-Cookie bleibt aktiv und stellt bei der nächsten Anfrage automatisch eine neue authentifizierte Session her, praktisch ein Logout, das gar nicht wirklich stattfindet. Symfonys eingebauter Logout-Handler löscht standardmäßig sowohl die Session als auch das Remember-Me-Cookie sowie den zugehörigen Datenbank-Eintrag, aber nur, wenn remember_me korrekt im Firewall-Logout-Konfigurationsblock verankert ist.
Ein zusätzlicher, oft übersehener Fall: Logout auf einem gemeinsam genutzten Gerät, etwa einem Kiosk-Rechner. Hier sollte die Anwendung aktiv anbieten, alle Remember-Me-Tokens des Benutzers zu löschen, nicht nur die aktuelle Serie, damit ein vergessenes Remember-Me-Cookie von einer anderen Sitzung nicht unbemerkt weiterhin gültig bleibt. Diese vollständige Bereinigung gehört zu einer ernsthaften Remember Me-Implementierung dazu, nicht nur der Standard-Logout der aktuellen Session.
<?php
declare(strict_types=1);
namespace App\Controller;
use App\Repository\PersistentTokenRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Core\User\UserInterface;
final class LogoutAllDevicesController extends AbstractController
{
#[Route('/account/logout-all', name: 'app_logout_all_devices', methods: ['POST'])]
public function __invoke(PersistentTokenRepository $tokens): JsonResponse
{
/** @var UserInterface $user */
$user = $this->getUser();
// Deletes every remember-me series for this user, not just the current one —
// essential for the "logout on a shared device" scenario
$deletedCount = $tokens->deleteAllForUser($user->getUserIdentifier());
return $this->json(['revoked_sessions' => $deletedCount]);
}
}
8. Geräteübersicht und gezielter Widerruf
Weil persistente Tokens in einer normalen Datenbanktabelle liegen, lässt sich daraus leicht eine Geräteübersicht für den Benutzer bauen, ähnlich wie bei größeren Plattformen üblich: eine Liste aktiver Remember-Me-Serien mit letztem Nutzungszeitpunkt, aus der jede einzelne Serie gezielt gelöscht werden kann. Das ist ein direkter praktischer Vorteil des persistenten Token-Modells gegenüber signierten Cookies, bei denen eine solche Übersicht technisch unmöglich ist.
Für Session Sicherheit in sicherheitsbewussten Projekten ist diese Übersicht mehr als ein Komfort-Feature: sie gibt Benutzern die Möglichkeit, selbst auf einen vermuteten Kontodiebstahl zu reagieren, ohne auf den Support angewiesen zu sein. Eine Kombination aus automatischer Rotation, Diebstahl-Erkennung bei wiederverwendeten alten Tokens und einer manuellen Geräteübersicht deckt die drei wichtigsten Verteidigungslinien für Remember Me in produktiven Anwendungen ab.
-- Device overview query — one row per active remember-me series
-- "series" is the stable per-device identifier, "value" changes on every rotation
SELECT
series,
last_used,
class AS user_class
FROM rememberme_token
WHERE username = :username
ORDER BY last_used DESC;
-- Targeted revocation of exactly one device/series
DELETE FROM rememberme_token
WHERE username = :username AND series = :series;
9. Remember-Me-Strategien im Vergleich
Die Wahl der richtigen Remember-Me-Strategie hängt von der Sensitivität der Anwendung ab. Die folgende Übersicht ordnet die verfügbaren Optionen nach Sicherheitsniveau und Implementierungsaufwand ein.
| Strategie | Gezielter Widerruf | Diebstahl-Erkennung | Empfehlung |
|---|---|---|---|
| Signiertes Cookie | Nicht möglich | Keine | Nur für unkritische Demos |
| Persistentes Token ohne Rotation | Möglich | Gering | Minimum für Produktion |
| Persistentes Token mit Rotation | Möglich | Hoch | Empfohlener Standard |
| + Geräteübersicht für Benutzer | Selbstbedienung | Hoch | Für sicherheitsbewusste Produkte |
Für die überwiegende Mehrheit produktiver Symfony-Anwendungen ist persistentes Token mit Rotation der richtige Kompromiss aus Sicherheit und Implementierungsaufwand. Eine zusätzliche Geräteübersicht lohnt sich vor allem für Anwendungen mit sensiblen Daten, bei denen Benutzer selbst aktiv auf einen Kontoverdacht reagieren können sollen, ohne den Support kontaktieren zu müssen.
Mironsoft
Session-Sicherheit, Login-Architektur und Symfony-Backend
Remember Me, das Komfort und Sicherheit vereint?
Wir migrieren bestehende Remember-Me-Implementierungen auf persistente Tokens mit Rotation, härten Session-Handling gegen Fixation und Diebstahl, und bauen Geräteübersichten mit gezieltem Widerruf.
Session-Audit
Bestehende Remember-Me- und Session-Konfiguration auf Lücken prüfen
Token-Migration
Signierte Cookies auf persistente, rotierende Tokens umstellen
Geräteübersicht
Selbstbedienungs-Widerruf für Benutzer implementieren
10. Zusammenfassung
Remember Me und Session Sicherheit gehören zusammen betrachtet, weil ein langlebiges Remember-Me-Cookie im Schadensfall deutlich länger wirksam bleibt als eine normale Session. Persistente Tokens mit Rotation ersetzen unsichere signierte Cookies, ermöglichen gezielten Widerruf und erkennen Diebstahl über wiederverwendete alte Tokens. Session-ID-Regenerierung bei Login und bei Rechteänderungen verhindert Session-Fixation zuverlässig.
Idle-Timeout, Absolute-Timeout und Remember-Me-Lebensdauer sind drei unabhängige Zeitgrenzen, die zusammen die tatsächliche Sicherheit bestimmen, kritische Aktionen sollten trotz gültigem Remember-Me-Cookie eine erneute Passwort-Bestätigung verlangen. Ein vollständiger Logout löscht Session, Remember-Me-Cookie und den zugehörigen Datenbank-Eintrag gemeinsam, eine Geräteübersicht gibt Benutzern zusätzliche Kontrolle über ihre aktiven Anmeldungen.
Remember Me und Session Sicherheit — Das Wichtigste auf einen Blick
Persistente Tokens statt signierter Cookies
Gezielter Widerruf einzelner Geräte ist nur mit Datenbank-basierten Tokens möglich, nicht mit signierten Cookies.
Token-Rotation als Diebstahl-Erkennung
Ein wiederverwendetes altes Token nach Rotation ist ein starkes Indiz für Diebstahl und sollte die gesamte Serie widerrufen.
Session-Fixation verhindern
Session-ID-Regenerierung bei Login und bei jeder signifikanten Rechteänderung ist Pflicht, niemals deaktivieren.
Drei unabhängige Zeitgrenzen
Idle-Timeout, Absolute-Timeout und Remember-Me-Lebensdauer müssen bewusst und getrennt konfiguriert werden.