SameSite-Cookie-Rezepte

Chrome, Firefox, Edge und andere werden ihr Standardverhalten gemäß dem IETF-Vorschlag Inkrementelle Better Cookies ändern, sodass:

  • Cookies ohne SameSite-Attribut werden wie SameSite=Lax behandelt. Das bedeutet, dass Cookies nur auf Erstanbieterkontexte beschränkt sind.
  • In Cookies für die websiteübergreifende Nutzung muss SameSite=None; Secure angegeben werden, damit sie in den Kontext von Drittanbietern aufgenommen werden können.

Diese Funktion ist die Standardeinstellung ab Chrome 84 (stabile Version). Falls noch nicht geschehen, sollten Sie die Attribute für Ihre Drittanbieter-Cookies aktualisieren, damit diese in Zukunft nicht blockiert werden.

Browserübergreifende Unterstützung

Weitere Informationen finden Sie auf der MDN-Seite Set-Cookie im Abschnitt Browserkompatibilität.

Anwendungsfälle für website- oder Drittanbieter-Cookies

Es gibt eine Reihe gängiger Anwendungsfälle und Muster, bei denen Cookies in einem Drittanbieterkontext gesendet werden müssen. Wenn Sie einen dieser Anwendungsfälle anbieten oder auf einen dieser Anwendungsfälle angewiesen sind, müssen Sie oder der Anbieter seine Cookies aktualisieren, damit der Dienst weiterhin korrekt funktioniert.

Inhalte in einem <iframe>

Inhalte einer anderen Website, die in einem <iframe> angezeigt werden, stammen aus dem Kontext eines Drittanbieters. Standardanwendungsfälle sind:

  • Eingebettete Inhalte, die von anderen Websites geteilt wurden, z. B. Videos, Karten, Codebeispiele und Beiträge in sozialen Netzwerken
  • Widgets von externen Diensten wie Zahlungen, Kalender, Buchungs- und Reservierungsfunktionen.
  • Widgets wie Schaltflächen für soziale Netzwerke oder Dienste zur Betrugsbekämpfung, die weniger offensichtliche <iframes>.

Cookies können hier unter anderem verwendet werden, um den Sitzungsstatus beizubehalten, allgemeine Einstellungen zu speichern, Statistiken zu aktivieren oder Inhalte für Nutzer mit bestehenden Konten zu personalisieren.

Diagramm eines Browserfensters, in dem die URL der eingebetteten Inhalte nicht mit der URL der Seite übereinstimmt.
Wenn die eingebetteten Inhalte nicht von derselben Website wie der Browserkontext auf oberster Ebene stammen, handelt es sich um Inhalte von Drittanbietern.

Da das Web von Natur aus zusammensetzbar ist, werden außerdem <iframes> verwendet, um Inhalte einzubetten, die auch in einem eigenen Kontext oder auf oberster Ebene angezeigt werden. Alle von dieser Website verwendeten Cookies gelten als Drittanbieter-Cookies, wenn die Website innerhalb des Frames angezeigt wird. Wenn Sie Websites erstellen, die von anderen Nutzern einfach eingebettet werden sollen und gleichzeitig auf Cookies angewiesen sind, müssen Sie auch diese für die websiteübergreifende Nutzung kennzeichnen oder dass ein Fallback ohne Cookies möglich ist.

„Unsichere“ Anfragen auf mehreren Websites

„Unsicher“ klingt hier zwar etwas besorgniserregend, aber dies bezieht sich auf jede Anfrage, mit der der Status geändert werden soll. Im Web sind das primär POST-Anfragen. Cookies, die als SameSite=Lax gekennzeichnet sind, werden bei sicheren Navigationen der obersten Ebene gesendet, z.B. wenn auf einen Link geklickt wird, um zu einer anderen Website zu gelangen. Ein Beispiel: <form>-Übermittlung per POST an eine andere Website würde jedoch keine Cookies enthalten.

Diagramm einer Anfrage, die von einer Seite zu einer anderen wechselt.
Wenn bei der eingehenden Anfrage eine „sichere“ Methode verwendet wird, werden die Cookies gesendet.

Dieses Muster wird für Websites verwendet, die den Nutzer möglicherweise an einen Remote-Dienst weiterleiten, um vor der Rückgabe einige Vorgänge auszuführen, z. B. zu einem externen Identitätsanbieter. Bevor der Nutzer die Website verlässt, wird ein Cookie mit einem Einmalnutzungstoken gesetzt. Es wird darauf geachtet, dass dieses Token für die zurückgegebene Anfrage überprüft werden kann, um Angriffe auf Cross-Site Request Forgery (CSRF) abzuschwächen. Wenn diese zurückgegebene Anfrage über POST eingeht, müssen die Cookies als SameSite=None; Secure gekennzeichnet werden.

Remote-Ressourcen

Jede Remote-Ressource auf einer Seite kann darauf angewiesen sein, dass Cookies mit einer Anfrage von <img>-Tags, <script>-Tags usw. gesendet werden. Gängige Anwendungsfälle sind beispielsweise das Tracking von Pixeln und die Personalisierung von Inhalten.

Dies gilt auch für Anfragen, die von fetch oder XMLHttpRequest über deinen JavaScript-Code initiiert werden. Wenn fetch() mit der Option credentials: 'include' aufgerufen wird, ist das ein guter Hinweis darauf, dass bei diesen Anfragen möglicherweise Cookies zu erwarten sind. Bei XMLHttpRequest sollten Sie nach Instanzen des Attributs withCredentials suchen, die auf true festgelegt sind. Dies ist ein guter Hinweis darauf, dass bei diesen Anfragen Cookies zu erwarten sind. Diese Cookies müssen entsprechend gekennzeichnet werden, um in websiteübergreifende Anfragen aufgenommen zu werden.

Inhalt in einem WebView

Ein WebView in einer plattformspezifischen App wird in einem Browser ausgeführt und du musst testen, ob dieselben Einschränkungen oder Probleme gelten. Wenn WebView in Android von Chrome unterstützt wird, werden die neuen Standardeinstellungen bei Chrome 84 nicht sofort angewendet. Es ist jedoch geplant, sie in Zukunft anzuwenden, Sie sollten also trotzdem Tests durchführen und sich darauf vorbereiten. Außerdem können plattformspezifische Apps von Android direkt über die CookieManager API Cookies setzen. Wie bei Cookies, die über Header oder JavaScript gesetzt werden, solltest du SameSite=None; Secure einfügen, wenn sie für die websiteübergreifende Verwendung bestimmt sind.

SameSite jetzt implementieren

Cookies, die nur in selbst erhobenen Daten benötigt werden, sollten je nach Bedarf als SameSite=Lax oder SameSite=Strict gekennzeichnet werden. Sie können auch einfach nichts unternehmen und dem Browser erlauben, die Standardeinstellung zu erzwingen. Das birgt jedoch das Risiko eines inkonsistenten Verhaltens in Browsern und potenziellen Konsolenwarnungen für jedes Cookie.

Set-Cookie: first_party_var=value; SameSite=Lax

Cookies, die im Zusammenhang mit Drittanbietern benötigt werden, müssen als SameSite=None; Secure gekennzeichnet sein. Beachten Sie, dass Sie beide Attribute zusammen benötigen. Wenn Sie nur None ohne Secure angeben, wird das Cookie abgelehnt. Es gibt jedoch einige Unterschiede zwischen Browserimplementierungen, die beide nicht kompatibel sind. Daher müssen Sie möglicherweise einige der Abhilfemaßnahmen anwenden, die unten im Abschnitt Umgang mit inkompatiblen Clients beschrieben sind.

Set-Cookie: third_party_var=value; SameSite=None; Secure

Inkompatible Clients verarbeiten

Da diese Änderungen um None und das Standardverhalten für Updates noch relativ neu sind, gibt es zwischen den Browsern Unstimmigkeiten im Hinblick darauf, wie diese Änderungen verarbeitet werden. Die derzeit bekannten Probleme findest du auf der Updates-Seite unter chromium.org. Es kann jedoch nicht angegeben werden, ob sie vollständig sind. Das ist zwar nicht ideal, doch in dieser Übergangsphase können Sie Abhilfemaßnahmen einsetzen. Als allgemeine Regel gilt jedoch, inkompatible Clients als Sonderfall zu behandeln. Erstellen Sie keine Ausnahme für Browser, die die neueren Regeln implementieren.

Die erste Möglichkeit besteht darin, sowohl das neue als auch das alte Cookie zu setzen:

Set-cookie: 3pcookie=value; SameSite=None; Secure
Set-cookie: 3pcookie-legacy=value; Secure

Browser, die das neuere Verhalten implementieren, setzen das Cookie mit dem Wert SameSite, während es von anderen Browsern möglicherweise ignoriert oder falsch gesetzt wird. Derselbe Browser setzt jedoch das Cookie 3pcookie-legacy. Bei der Verarbeitung eingeschlossener Cookies sollte die Website zuerst prüfen, ob das neue Stilcookie vorhanden ist. Wird es nicht gefunden, sollte auf das alte Cookie zurückgegriffen werden.

Das folgende Beispiel zeigt, wie dies in Node.js unter Verwendung des Express-Frameworks und seiner cookie-parser-Middleware funktioniert.

const express = require('express');
const cp = require('cookie-parser');
const app = express();
app.use(cp());

app.get('/set', (req, res) => {
  // Set the new style cookie
  res.cookie('3pcookie', 'value', { sameSite: 'none', secure: true });
  // And set the same value in the legacy cookie
  res.cookie('3pcookie-legacy', 'value', { secure: true });
  res.end();
});

app.get('/', (req, res) => {
  let cookieVal = null;

  if (req.cookies['3pcookie']) {
    // check the new style cookie first
    cookieVal = req.cookies['3pcookie'];
  } else if (req.cookies['3pcookie-legacy']) {
    // otherwise fall back to the legacy cookie
    cookieVal = req.cookies['3pcookie-legacy'];
  }

  res.end();
});

app.listen(process.env.PORT);

Der Nachteil ist, dass hierbei redundante Cookies gesetzt werden, die alle Browser abdecken, und dass Änderungen sowohl beim Festlegen als auch beim Lesen des Cookies vorgenommen werden müssen. Dieser Ansatz sollte jedoch alle Browser unabhängig von ihrem Verhalten abdecken und dafür sorgen, dass Drittanbieter-Cookies weiterhin wie gewohnt funktionieren.

Wenn der Set-Cookie-Header gesendet wird, kannst du den Client auch über den User-Agent-String erkennen. Sehen Sie sich die Liste der inkompatiblen Clients an und verwenden Sie dann eine geeignete Bibliothek für Ihre Plattform, z. B. die ua-parser-js-Bibliothek auf Node.js. Es empfiehlt sich, eine Bibliothek für die User-Agent-Erkennung zu verwenden, da Sie diese regulären Ausdrücke höchstwahrscheinlich nicht selbst schreiben möchten.

Der Vorteil dieses Ansatzes besteht darin, dass beim Setzen des Cookies nur eine Änderung erforderlich ist. Die notwendige Warnung besagt jedoch, dass das User-Agent-Sniffing inhärent instabil ist und möglicherweise nicht alle betroffenen Nutzer erfasst.

Unterstützung für SameSite=None in Sprachen, Bibliotheken und Frameworks

Die meisten Sprachen und Bibliotheken unterstützen das Attribut SameSite für Cookies. Das Hinzufügen von SameSite=None ist jedoch noch relativ neu, sodass Sie möglicherweise einige Standardfunktionen vorerst umgehen müssen. Diese sind im SameSite-Beispiel-Repository auf GitHub dokumentiert.

Unterstützung erhalten

Cookies gibt es überall und es kommt selten vor, dass eine Website vollständig geprüft hat, wo sie platziert und verwendet werden, insbesondere wenn Sie websiteübergreifende Anwendungsfälle ins Gedächtnis rufen. Wenn ein Problem auftritt, ist es vielleicht das erste Mal, dass jemand darauf gestoßen ist. Zögern Sie also nicht, sich an uns zu wenden: