Cookies sind die älteste Web-Storage-Schicht und gleichzeitig das wichtigste Auth-Vehikel. Die Anzahl der Attribute und Quirks ist groß: Secure, HttpOnly, SameSite, Path, Domain, Max-Age, Expires, die strukturellen Präfixe __Host- und __Secure-, plus der seit 2024 verbreitete Partitioned-Flag für Storage-Partitioning. Dieser Artikel liefert eine vollständige Referenz inkl. Quirks pro Browser.
Cookie-Anatomie
Set-Cookie: name=value;
Domain=example.com;
Path=/;
Max-Age=86400;
Expires=Mon, 17 May 2027 12:00:00 GMT;
HttpOnly;
Secure;
SameSite=Lax;
PartitionedPro Cookie ein Set-Cookie-Header (mehrere Cookies = mehrere Header).
| Attribut | Wert | Default | Bedeutung |
|---|---|---|---|
Domain | Domain-String | aktueller Host (Host-Only) | Cookie gilt für diese Domain plus Subdomains |
Path | Pfad-String | / (bzw. Request-Pfad) | Cookie nur für diesen Pfad und Sub-Pfade |
Max-Age | Sekunden | (kein Default) | Lebenszeit ab jetzt (überschreibt Expires) |
Expires | Datum | (kein Default) | Absoluter Ablauf-Zeitpunkt |
Secure | (boolean) | aus | Nur über HTTPS senden |
HttpOnly | (boolean) | aus | JS via document.cookie kann nicht lesen |
SameSite | Strict/Lax/None | Lax (modern) | Cross-Site-Verhalten |
Partitioned | (boolean) | aus | Cookie wird pro Top-Frame-Site partitioniert (CHIPS) |
Priority | Low/Medium/High | Medium | Browser-Eviction-Reihenfolge (Chromium-only) |
Secure, HttpOnly, SameSite — die drei Sicherheits-Flags
Vertieft in session-cookies (Kap 14). Hier nochmal kompakt:
Secure — Cookie wird nur über HTTPS gesendet. Pflicht für alle Auth-Cookies. Lokales localhost ohne TLS akzeptiert Secure als Default (moderne Browser).
HttpOnly — JS via document.cookie kann den Cookie nicht lesen. Pflicht für Session-Cookies — gegen XSS-Cookie-Diebstahl. Limitation: schützt nicht vor XSS-via-fetch-with-credentials.
SameSite — Cross-Site-Verhalten:
Strict— nie bei Cross-Site-Requests. Klick auf externen Link zur Seite → kein Cookie → User scheint nicht eingeloggt.Lax(Default seit 2020) — bei Cross-Site nur bei Top-Level-GET. Klassische CSRF-Schutz-Schicht.None— immer, auch Cross-Site. ErfordertSecure-Flag.
Mehr in samesite-cookies (Kap 12).
Path und Domain
Path — Cookie gilt nur für Requests, deren URL mit diesem Pfad beginnt. Default ist der Pfad des Set-Cookie-Requests.
Path=/— gilt überall.Path=/api— gilt für/api,/api/users,/api/v2/....Path=/admin— gilt nur für Admin-Bereich.
Wichtig: Path ist kein Sicherheits-Mechanismus. Der Browser sendet das Cookie nur an passenden Pfaden, aber JS auf der Seite kann mit document.cookie Cookies nicht-passender Pfade trotzdem nicht sehen — heißt nicht, dass andere Pfade „sicher" vor diesem Cookie sind.
Domain — wenn nicht gesetzt: Host-Only-Cookie (gilt nur für exakt diesen Host).
Wenn gesetzt: gilt für diese Domain plus alle Subdomains.
# Auf app.example.com gesetzt, OHNE Domain
Set-Cookie: x=1
→ gilt nur für app.example.com
# Auf app.example.com gesetzt MIT Domain=example.com
Set-Cookie: x=1; Domain=example.com
→ gilt für example.com, app.example.com, blog.example.com, beliebige.example.comSicherheits-Implication: wer Domain=example.com setzt, gibt Subdomain-Sicht. Wenn blog.example.com XSS hat, sieht JS dort das Cookie. Empfehlung: Domain weglassen außer wenn explizit Multi-Subdomain-Sharing gewollt ist.
__Host- und __Secure-Präfixe
Browser-erzwungene Garantien per Naming-Convention.
__Host--Präfix:
Cookies mit Namen __Host-... werden vom Browser nur akzeptiert, wenn:
Securegesetzt.Path=/gesetzt.- Kein
Domain-Attribut (Host-Only).
Set-Cookie: __Host-sessionId=abc; Secure; HttpOnly; SameSite=Lax; Path=/
# Browser akzeptiert ✓Was es garantiert:
- Cookie kann nur über HTTPS gesendet werden.
- Cookie ist auf den exakten Host beschränkt — keine Subdomain kann es schreiben oder lesen.
- Cookie ist für die ganze Site gültig (Path=/).
Wenn der Server ein __Host--Cookie ohne die Bedingungen setzt, lehnt der Browser das Cookie ab — kein Set-Cookie wirksam. Strukturelle Garantie.
__Secure--Präfix:
Schwächer als __Host-. Cookies mit Namen __Secure-... werden nur akzeptiert, wenn Secure gesetzt ist. Erlaubt Domain und Path != /.
Empfehlung: Für Session-Cookies __Host--Präfix nutzen. Für andere sicherheits-relevante Cookies (CSRF-Token, Refresh-Token, etc.) ebenfalls.
Max-Age und Expires
Beide steuern die Cookie-Lebenszeit:
Max-Agein Sekunden (z. B.Max-Age=86400= 1 Tag). Relativ zur Set-Zeit.Expiresals absolutes Datum (RFC 1123 / RFC 7231 Format).- Wenn beide gesetzt:
Max-Agegewinnt (in modernen Browsern). - Wenn keines gesetzt: Session-Cookie — wird beim Browser-Schließen gelöscht (in der Theorie; Browser mit „Session restore on restart" behalten sie de facto).
Sicherheits-Implikation:
- Auth-Cookies sollten explizites Max-Age haben (typisch 1 Tag bis 1 Woche).
- Sehr lange Lebenszeiten (1 Jahr+) sind ein Risiko — bei Cookie-Diebstahl bleibt der Zugang lange offen.
- Session-Cookies ohne Max-Age klingen sicher, sind aber bei „Restore Session"-Verhalten praktisch persistent.
Cookie-Löschung:
# Cookie mit Vergangenheits-Datum oder Max-Age=0 wird gelöscht
Set-Cookie: name=; Path=/; Max-Age=0
Set-Cookie: name=; Path=/; Expires=Thu, 01 Jan 1970 00:00:00 GMT
# WICHTIG: alle Attribute (Path, Domain) müssen mit dem ursprünglichen Cookie übereinstimmen,
# sonst wird ein NEUES Cookie gesetzt statt das alte gelöschtPartitioned (CHIPS) — Storage-Partitioning
Seit 2024 verbreitet: Cookies Having Independent Partitioned State (CHIPS).
Problem: Drittpartei-Cookies sind in modernen Browsern stark eingeschränkt (Safari ITP seit 2017, Chrome 2024). Manche legitime Use-Cases (Embed-Widgets, SSO-iframes) brauchen aber Cookie-Storage in cross-site Kontexten.
CHIPS-Lösung: Cookie mit Partitioned-Flag wird pro Top-Frame-Site partitioniert.
Set-Cookie: widget_pref=dark; SameSite=None; Secure; PartitionedEffekt: wenn das Widget von widget.example.com auf siteA.com eingebettet ist, gibt es ein partitioniertes Cookie für die Kombination (widget.example.com, siteA.com). Beim Embed auf siteB.com ist es ein anderer, separater Cookie-Storage.
Wann nutzen:
- 3rd-Party-Widgets (Embed-Maps, Chat-Widgets, Embed-Videos), die User-Preferences pro Hosting-Site brauchen.
- 3rd-Party-Auth-Widgets (limitiert — Cross-Site-SSO ist mit Partitioning eingeschränkt).
Wann nicht:
- 1st-Party-Auth-Cookies —
Partitionedist da überflüssig oder kontraproduktiv.
Konfiguration in den wichtigsten Frameworks
Express:
res.cookie('sessionId', sessionId, {
httpOnly: true,
secure: true,
sameSite: 'lax',
path: '/',
maxAge: 24 * 60 * 60 * 1000, // in ms (anders als HTTP-Header in Sekunden!)
// Für __Host-Präfix: Cookie-Name beginnt mit __Host-
});
// Mit __Host-Präfix
res.cookie('__Host-sessionId', sessionId, {
httpOnly: true,
secure: true,
sameSite: 'lax',
path: '/',
});Django:
response.set_cookie(
'__Host-sessionid',
value=session_id,
max_age=86400,
secure=True,
httponly=True,
samesite='Lax',
)Spring (Java):
ResponseCookie cookie = ResponseCookie.from("__Host-sessionId", sessionId)
.httpOnly(true)
.secure(true)
.sameSite("Lax")
.path("/")
.maxAge(Duration.ofDays(1))
.build();
response.addHeader(HttpHeaders.SET_COOKIE, cookie.toString());Cookie-Größen-Limits und Quirks
Pro Cookie ~4 KB. Bei mehr blockiert der Browser das Cookie still oder die Server-Request-Header werden zu groß (HTTP 431-Fehler bei strikten Reverse-Proxies).
Maximale Cookie-Anzahl pro Domain: Browser-spezifisch (typisch 50–300). Bei Apps mit vielen Cookies (Marketing-Tags) kann das eng werden.
Encoding: Cookie-Werte dürfen einige Sonderzeichen nicht enthalten (Komma, Semikolon, Whitespace, Backslash, Doppelhochkommas). Pattern: URL-encode des Werts vor Set, decode beim Read.
Cookie ohne Quotes:
# OK
Set-Cookie: x=hello-world
# Problematisch (Komma wird teilweise als zweiter Cookie interpretiert)
Set-Cookie: x=hello, world
# Mit Encoding
Set-Cookie: x=hello%2C%20worldSameSite=None-Quirk: vor 2020 war SameSite=None ohne Secure möglich. Heute Pflicht — Browser akzeptiert sonst nicht. Wer es noch übersieht: Cookie wird still verworfen, Auth ist broken.
FAQ
Wann __Host- vs. __Secure-?
__Host- erzwingt zusätzlich Path=/ und Host-Only. Maximal restriktiv. Für klassische Session-Cookies einer App immer __Host-. __Secure- ist die abgeschwächte Variante, wenn du Domain oder Path != / brauchst — etwa für ein Cookie, das auch von Subdomains lesbar sein soll. Default-Wahl: __Host-.
Brauche ich noch Session-Cookies oder reichen JWTs?
Beides hat Trade-offs (siehe jwt-stateless-tokens). Für klassische Web-Apps mit Server-Rendering ist Session-Cookie mit __Host- und HttpOnly meistens einfacher und sicherer. JWTs lohnen sich bei Microservice-Architekturen und Mobile-Clients.
SameSite=Strict bricht Onboarding-Flows
Klassischer Onboarding-Flow: User registriert sich, klickt auf Verifikations-Link in Mail, landet auf der App. Wenn das Auth-Cookie SameSite=Strict ist, wird es bei Klick aus der Mail (Cross-Site) nicht gesendet — User erscheint nicht eingeloggt. Pattern: SameSite=Lax für Standard, Strict nur für sehr sensitive Bereiche (Banking-Transfer).
Wann brauche ich Partitioned-Cookies?
Wenn deine App ein Drittpartei-Widget auf fremden Sites hostet (Chat-Bubble, Calendar-Widget, Embed-Map), und du dort User-Preferences pro Hosting-Site speichern willst. Für 1st-Party-Apps (User lädt deine App direkt im Browser) ist Partitioning irrelevant.
Cookie-Banner-Pflicht (DSGVO/TTDSG)
Nicht alle Cookies brauchen Consent. Strikt notwendige (Session, Auth, Warenkorb) sind ohne Consent erlaubt (DSGVO Art. 6 Abs. 1 lit. b). Tracking-, Analytics- und Marketing-Cookies brauchen Opt-In. Cookie-Banner ist die UI-Schicht; die Cookies selbst sollten erst nach Zustimmung gesetzt werden. Vertieft in Kap 5.
Cookie-Hijacking nach DOM-Cookie-Override
Wenn ein JS-zugängliches Cookie (kein HttpOnly) den Wert eines HttpOnly-Cookies überschreibt, kommt es auf die Reihenfolge an. Browser-Behavior ist Standard: das zuletzt gesetzte gleichnamige Cookie gewinnt. Pattern: kritische Cookies immer mit __Host-Präfix und HttpOnly, plus eindeutigen Namen.
document.cookie vs. CookieStore API
Die alte API ist document.cookie — synchron, langsam. Die CookieStore API ist die moderne async Alternative, mit besserer Promise-basierter Semantik und Change-Events. Stand 2026 in Chromium und Firefox; Safari noch nicht voll. Für neue Code-Bases erwägen.
Weiterführende Ressourcen
Externe Quellen
- RFC 6265 — HTTP State Management Mechanism
- RFC 6265bis — Cookies (Update)
- MDN — Set-Cookie
- web.dev — SameSite Cookies Explained
- MDN — Partitioned Cookies (CHIPS)
- OWASP — HttpOnly
- OWASP Session Management Cheat Sheet
Verwandte Artikel
- Session-Cookies (Kap 14)
- SameSite-Cookies (Kap 12)
- CSRF-Grundlagen (Kap 12)
- Secure-Headers-Übersicht
- HSTS und HTTPS-Only
- Cookies und LocalStorage (Nutzer-Sicht) (Kap 5)