SameSite-Cookies sind die wichtigste browser-seitige Schutz-Schicht gegen CSRF — und seit 2020 in Chrome standardmäßig aktiv. Wer eine moderne Web-App baut, kann von einer Basis-Schutz-Schicht ausgehen, die ohne Code-Änderung wirkt. Aber: die Schutzwirkung hat klare Grenzen. Dieser Artikel zeigt die drei SameSite-Werte, die Browser-Defaults, die häufigen Edge-Cases und die bekannten Bypass-Patterns.
Was SameSite tut
Cookies haben seit RFC 6265 das Attribut SameSite, das steuert, wann der Browser den Cookie bei Cross-Site-Anfragen mitsendet.
Drei Werte:
SameSite=None— Cookie wird bei jedem Request mitgeschickt, auch cross-site. Klassisches Verhalten vor SameSite. Muss heute mitSecurekombiniert sein.SameSite=Lax— Cookie wird nicht bei Cross-Site-Anfragen mitgesendet, außer bei Top-Level-GET-Navigation (Klick auf Link, Adressleiste-Eingabe). Browser-Default seit 2020.SameSite=Strict— Cookie wird bei keinem Cross-Site-Request mitgesendet, auch nicht bei Link-Klicks. Strengster Modus.
Konkretes Beispiel:
Du bist auf evil.example, dort gibt es:
<form action="https://bank.example/transfer" method="POST">
<input name="to" value="attacker">
<input name="amount" value="10000">
</form>
<script>document.forms[0].submit();</script>Was passiert mit deinem Bank-Session-Cookie?
| Cookie-Setting | Wird bei dieser POST-Anfrage mitgeschickt? |
|---|---|
SameSite=None (alte Default) | Ja → CSRF funktioniert |
SameSite=Lax (neuer Default) | Nein (POST ist nicht Top-Level-GET-Navigation) → CSRF scheitert |
SameSite=Strict | Nein → CSRF scheitert |
Mit Lax als Default ist der klassische Auto-Submitting-Form-CSRF-Angriff strukturell tot — der Cookie fehlt, die Bank sieht eine nicht-authentifizierte Anfrage.
Was „Same-Site" wirklich heißt
Der Begriff ist verwirrend: „Same-Site" ist nicht dasselbe wie „Same-Origin".
Same-Origin:
- Schema (HTTP vs. HTTPS) muss übereinstimmen.
- Host muss exakt übereinstimmen.
- Port muss übereinstimmen.
https://bank.exampleundhttps://app.bank.examplesind verschiedene Origins.
Same-Site:
- Vergleicht nur die registrierbare Domain (eTLD+1).
https://bank.exampleundhttps://app.bank.examplesind dieselbe Site.https://bank.exampleundhttp://bank.examplesind dieselbe Site (gleiche eTLD+1; Schema egal — bis 2021, seit Chrome 88 mit „schemeful same-site" auch Schema-relevant).https://example.co.ukundhttps://other.co.uksind verschiedene Sites (eTLD+1 berücksichtigt Public Suffix List).
Konsequenz: SameSite-Cookies gelten innerhalb deiner gesamten registrierbaren Domain. Anfragen von app.bank.example zu api.bank.example sind „same-site", Cookies werden mitgesendet — selbst wenn die JavaScript-Origin streng anders ist.
Das ist auch der häufigste Grund, warum Sites manchmal explizit SameSite=None setzen müssen — wenn Authentifizierung über eine völlig getrennte Domain läuft (z. B. bank.com und bank-api.io).
Die Browser-Defaults im Detail
Stand 2026 — wann ist Lax der Default?
| Browser | Lax-Default seit | Schemeful Same-Site |
|---|---|---|
| Chrome / Edge / Opera (Chromium) | Chrome 80 (Februar 2020) | Chrome 88+ |
| Firefox | Firefox 96 (Januar 2022) | Firefox 96+ |
| Safari | Safari 13 (2019), mit Eigenheiten | Schemeful seit Safari 13+ |
Wichtige Eigenheit von Safari: Apple hat eigene Heuristiken für Tracker-Schutz, die mit SameSite interagieren. Manche Cookies werden in Safari aggressiver behandelt als der Standard verlangt — gut für Datenschutz, manchmal überraschend für Entwickler.
Sonderfall „SameSite=None ohne Secure":
Vor 2020 war es üblich, Cookies ohne SameSite-Attribut zu setzen — die wurden als „None" behandelt. Seit dem Lax-Default werden Cookies ohne Attribut als Lax interpretiert. Wer explizit SameSite=None setzen will, muss zusätzlich Secure setzen — sonst lehnt der Browser das Cookie komplett ab.
Set-Cookie: session=abc; SameSite=None; Secure; Path=/; HttpOnlyVergiss Secure → Cookie kommt gar nicht erst beim Client an. Verbreitete Stolperfalle bei Sub-Domain-Auth-Setups.
Der GET-Side-Effect-Bypass
SameSite=Lax schickt Cookies bei Top-Level-GET-Navigation mit — wenn die Nutzer:in auf einen Link klickt, die Adressleiste eingibt, oder per window.location = '...' navigiert.
Wenn deine Anwendung GET-Endpunkte mit Side-Effects hat, bleibt CSRF möglich:
<!-- Auf evil.example -->
<a href="https://bank.example/transfer?to=attacker&amount=10000"
target="_blank">Wichtiger Link!</a>Wenn die Nutzer:in klickt — Top-Level-GET-Navigation, Cookies werden mit Lax-Default mitgeschickt — und die GET-Aktion wird ausgeführt.
Schutz:
- GET sollte niemals Side-Effects haben. RESTful-Disziplin: GET ist read-only, POST/PUT/DELETE für State-Changes.
- Wenn legacy GET-Endpoints mit Wirkung existieren:
SameSite=Strictfür die Auth-Cookies setzen — dann werden sie auch bei Top-Level-Navigation nicht mitgeschickt.
Lax-Allowing-Methods im Browser:
In Chrome 91 (2021) wurde die Liste der erlaubten Methoden für Lax weiter eingeschränkt — nur noch GET, nicht mehr POST, was kurz nach dem ursprünglichen Rollout möglich war (in einem 2-Minuten-Fenster nach Cookie-Setzen). Stand 2026: nur GET ist „Lax-allowing".
Subdomain-Edge-Cases
SameSite trennt nicht zwischen Subdomains derselben Site. Wenn app.example.com und cdn.example.com zur selben Site gehören:
- Cookie auf
example.commitSameSite=Laxwird bei Anfragen von beiden Subdomains mitgesendet. - Wenn
cdn.example.comXSS hat oder vom Angreifer kontrolliert wird, kann sie Anfragen mit dem Auth-Cookie anapp.example.commachen.
Konsequenzen:
- Subdomain-Hygiene ist wichtig: jede Subdomain ist potenziell Teil der Auth-Sphäre.
- User-Generated-Content-Subdomains (z. B.
*.usercontent.example.comfür User-Uploads) müssen strikt getrennt sein von der Haupt-Auth-Domain — entweder anderer registrierbarer Domain, oder Cookies mitDomain=app.example.com(nichtDomain=example.com). __Host--Cookie-Prefix: Cookies mit dem Namen-Präfix__Host-dürfen keinDomain-Attribut haben und keinPathaußer/. Der Browser erzwingt, dass das Cookie nur an die exakte Origin geliefert wird — sauberster Schutz für Auth-Cookies.
Set-Cookie: __Host-session=abc; SameSite=Lax; Secure; Path=/; HttpOnlyDieses Cookie ist:
- Nur auf der exakten Origin gültig (kein Subdomain-Sharing).
- Nur HTTPS (
Secure). - Nur Top-Level (
Path=/). - Nur Server-zugänglich (
HttpOnly). SameSite=Lax.
Das ist die modernste Cookie-Härtung für Auth-Cookies — Industrie-Standard für neue Apps.
Lax vs. Strict — wann was?
Beide Werte schützen vor klassischem CSRF. Wann nimmt man welches?
SameSite=Lax (Empfehlung für Auth-Cookies):
- Cookie wird bei Top-Level-GET-Navigation mitgesendet → Link-Klick zu deiner Site funktioniert mit Session.
- Beispiel: Nutzer:in kommt von Google-Suche auf deine Site, ist eingeloggt — funktioniert.
- Für die meisten Apps die richtige Wahl.
SameSite=Strict:
- Cookie wird bei gar keinem Cross-Site-Request mitgesendet.
- Klick von externer Seite (Google-Suche, Mail-Link) → Cookie fehlt, User ist als nicht eingeloggt dargestellt.
- Erst beim zweiten Klick innerhalb der Site greift das Cookie.
- Komfort-Einschränkung, aber stärkster Schutz.
Hybrid-Pattern: Manche Sites setzen zwei Cookies — ein SameSite=Strict für sensitive Aktionen (das den User „voll authentifiziert" macht) und ein SameSite=Lax als „du bist schon mal hier gewesen"-Marker. Erste Klicks von extern: User ist „erkannt", aber muss für Geld-Aktionen erneut bestätigen.
Spezialfälle für Strict:
- Online-Banking (jede sensitive Aktion ist es wert).
- Admin-Panels.
- High-Value-Aktionen (Krypto-Wallets, Trading).
Für Mainstream-Apps ist Lax Default — Strict bei Bedarf.
Bekannte Bypass-Patterns
Trotz SameSite-Default gibt es Bypass-Vektoren, die in spezifischen Konstellationen funktionieren:
Bypass 1 — GET mit Side-Effect.
Siehe Abschnitt 4. Wenn die App GET-Endpunkte mit Wirkung hat und der Cookie Lax ist, kommt der Cookie per Link-Klick mit. Schutz: Strict oder keine GET-Side-Effects.
Bypass 2 — Sub-Domain-XSS.
Subdomains teilen sich Cookies. Wenn support.example.com XSS hat, kann dort JS Cookies lesen (sofern nicht HttpOnly) oder Cross-Subdomain-Requests stellen. Schutz: __Host--Cookies + strikte Subdomain-Trennung.
Bypass 3 — SameSite=None-Cookies.
Wer aus Notwendigkeit None setzt, ist wieder auf klassischer CSRF-Angriffsfläche. Schutz: CSRF-Token zusätzlich.
Bypass 4 — SameSite-Defaults umgehen über CORS.
Manche fortgeschrittene Vektoren mit CORS-Bypass-Tricks (z. B. Access-Control-Allow-Credentials: true plus bestimmte Origin-Konfigurationen) können in seltenen Fällen umgehen. Schutz: CORS strict konfigurieren, Allowlist statt Wildcard.
Bypass 5 — Browser-Bugs.
In den ersten Monaten nach Lax-Default-Rollout 2020 wurden mehrere Browser-Bugs gefunden, die SameSite umgehen ließen. Alle gepatcht. Wer alte Browser zulässt, ist potenziell betroffen.
Bypass 6 — Lax + 2-Minuten-Fenster (historisch).
Ursprünglich erlaubte Chrome 2 Minuten nach Cookie-Setzen, dass Lax auch POST mitschickte — als Übergangs-Vermittlung. Seit Chrome 91 entfernt. Nur historisch relevant.
Praktische Empfehlung
Für eine neue Web-App im Jahr 2026:
Default-Cookie-Konfiguration:
Set-Cookie: __Host-session=abc;
HttpOnly;
Secure;
SameSite=Lax;
Path=/Plus:
- GET-Endpunkte ohne Side-Effects — RESTful-Disziplin.
- CSRF-Tokens in klassischen Form-basierten Workflows als Defense-in-Depth.
- Origin-Check als zusätzliche Server-side-Schicht.
- Re-Auth bei sensitiven Aktionen.
Damit ist die CSRF-Angriffsfläche praktisch geschlossen. Was bleibt: OAuth-Flows (eigenes Thema, csrf-in-oauth-und-saml) und exotische Edge-Cases mit SameSite=None-Notwendigkeit.
Besonderheiten
Chromes Lax-Default-Rollout 2020 hatte Nebenwirkungen
Februar 2020 rollte Chrome den Lax-Default schrittweise aus — und überraschte viele Sites, die Cross-Domain-Auth-Flows ohne explizites SameSite=None nutzten. Mail-Login-Workflows, Embedded-Widgets, manche OAuth-Provider hatten kurzzeitige Ausfälle. Lehre: Sicherheits-Defaults zu kippen ist eine massive Operation; Browser-Hersteller machen das nur, wenn der Nutzen sehr klar ist.
Schemeful Same-Site seit Chrome 88
Seit Chrome 88 (2021) sind http://example.com und https://example.com für SameSite-Zwecke verschiedene Sites. Bedeutet: Cookies, die auf HTTPS gesetzt wurden, gehen nicht bei HTTP-Anfragen mit — was Mixed-Content-Sicherheit verstärkt.
Public Suffix List entscheidet die eTLD+1
Was als „registrierbare Domain" gilt, ist nicht trivial. example.co.uk hat eTLD+1 = example.co.uk (weil co.uk als „Public Suffix" gilt). Die Public Suffix List wird von Mozilla gepflegt und von Browsern für SameSite-Logik benutzt.
GitHub und der Sub-Domain-Workaround
GitHub hostet User-Pages auf username.github.io. Diese Subdomains gelten nicht als Sub-Sites von github.io — weil github.io in der Public Suffix List steht. Damit haben User-Sites keine Cookie-Beziehung zur GitHub-Haupt-Domain. Sehr smart designed, schützt vor User-Content-XSS-zu-Auth-Cookie-Diebstahl.
iOS in-App-Browser haben SameSite-Quirks
WKWebView und SFSafariViewController auf iOS haben teils eigene Cookie-Handling-Eigenschaften. Apps, die OAuth-Flows in WebViews durchführen, sehen manchmal unerwartetes SameSite-Verhalten. Lehre: Native In-App-OAuth besser über System-Browser (ASWebAuthenticationSession) statt eingebetteter WebView.
Cookies vs. Storage — verschiedene Mechanismen
SameSite gilt für Cookies. localStorage und sessionStorage sind von Anfang an Origin-gebunden — sie werden gar nicht cross-site mitgesendet (keine HTTP-Request-Beziehung). Wer Auth über localStorage macht, hat strukturell anderes CSRF-Profil — kein automatisches Mitsenden, keine SameSite-Sorgen, dafür XSS-Auslese-Risiko.
Privacy-Sandbox und der zukünftige Wegfall von Third-Party-Cookies
Google plant seit Jahren, Third-Party-Cookies in Chrome komplett zu deaktivieren. Stand 2026 ist die Roadmap mehrfach verschoben worden. Was bedeutet das für SameSite? Wenig — SameSite gilt für First-Party- und Same-Site-Cookies; die Third-Party-Cookie-Diskussion ist orthogonal. Mehr in Cookies und LocalStorage.
Weiterführende Ressourcen
Externe Quellen
- IETF — Cookies (rfc6265bis-Draft, SameSite-Spezifikation)
- web.dev — SameSite Cookies Explained
- MDN — SameSite Cookie Attribute
- web.dev — Schemeful Same-Site
- Chrome Platform Status — SameSite Lax Default
- Public Suffix List
- OWASP — SameSite Cookies Cheat Sheet
- PortSwigger Research — SameSite Bypass