Przepisy na ciastka SameSite

Chrome, Firefox, Edge i inne firmy będą zmieniać swoje domyślne działanie zgodnie z propozycją IETF wzrostowo lepszej jakości plików cookie w taki sposób, aby:

  • Pliki cookie bez atrybutu SameSite będą traktowane jako SameSite=Lax, co oznacza, że domyślnym działaniem będzie ograniczenie plików cookie tylko do własnych kontekstów.
  • Pliki cookie używane do użycia w innych witrynach muszą mieć wartość SameSite=None; Secure, aby umożliwić uwzględnienie w kontekście strony trzeciej.

Jest to domyślne działanie od wersji stabilnej Chrome 84. Zaktualizuj atrybuty plików cookie innych firm, aby nie były blokowane w przyszłości.

Obsługa różnych przeglądarek

Zapoznaj się z sekcją Zgodność przeglądarek na stronie MDN Set-Cookie.

Przypadki użycia plików cookie z innych witryn lub plików cookie innych firm

Istnieje wiele typowych przypadków użycia i wzorców, w przypadku których pliki cookie muszą być wysyłane w kontekście firmy zewnętrznej. Jeśli podasz jeden z tych przypadków użycia lub będziesz z niego korzystać, upewnij się, że albo Ty albo dostawca aktualizujesz pliki cookie, aby usługa nadal działała prawidłowo.

Treści w: <iframe>

Treści z innej witryny wyświetlane w <iframe> są w kontekście zewnętrznym. Oto standardowe przypadki użycia:

  • Umieszczone treści udostępnione z innych witryn, takie jak filmy, mapy, przykłady kodu i posty społecznościowe.
  • widżety z usług zewnętrznych, takich jak płatności, kalendarze, rezerwacje i rezerwacje;
  • Widżety, np. przyciski społecznościowe czy usługi do zapobiegania oszustwom, które tworzą mniej oczywiste <iframes>.

Pliki cookie mogą być tu używane między innymi do utrzymywania stanu sesji, przechowywania ogólnych preferencji, generowania statystyk lub personalizowania treści dla użytkowników mających istniejące konta.

Schemat okna przeglądarki, w którym adres URL umieszczonej treści nie pasuje do adresu URL strony.
Jeśli umieszczone treści nie pochodzą z tej samej witryny co kontekst przeglądania najwyższego poziomu, są to treści należące do osoby trzeciej.

Poza tym sieć jest z natury kompozycyjna, więc <iframes> służy do umieszczania treści, które są również wyświetlane na poziomie nadrzędnym lub własnym. Wszystkie pliki cookie używane przez tę witrynę będą traktowane jako pliki cookie innych firm, gdy witryna wyświetli się w ramce. Jeśli tworzysz witryny, które zamierzasz łatwo umieszczać w witrynach, a jednocześnie polegać na plikach cookie, musisz się też upewnić, że są one oznaczone do użytku w różnych witrynach lub że możesz je stosować w sposób zastępczy.

„Niebezpieczne” żądania przesyłane między witrynami

Choć stwierdzenie „niebezpieczne” może wydawać się w tym przypadku nieco niepokojące, odnosi się do każdego żądania, które może mieć na celu zmianę stanu. W internecie są to głównie żądania POST. Pliki cookie oznaczone jako SameSite=Lax będą wysyłane podczas bezpiecznej nawigacji najwyższego poziomu, np. po kliknięciu linku do innej witryny. Jednak wysyłanie żądań <form> za pomocą metody POST do innej witryny nie zawiera plików cookie.

Diagram żądania przenoszonego z jednej strony na drugą.
Jeśli przychodzące żądanie używa bezpiecznej metody, pliki cookie są wysyłane.

Ten wzorzec jest używany w przypadku witryn, które mogą przekierowywać użytkownika do usługi zdalnej w celu wykonania jakiejś operacji przed jej zwróceniem, na przykład do zewnętrznego dostawcy tożsamości. Zanim użytkownik opuści witrynę, ustawiany jest plik cookie zawierający pojedynczy token użycia z oczekiwaniami, że token ten może zostać sprawdzony w powracającym żądaniu w celu ograniczenia ataków CSRF. Jeśli zwracane żądanie jest wysyłane metodą POST, musisz oznaczyć pliki cookie jako SameSite=None; Secure.

Zasoby zdalne

Każdy zasób zdalny na stronie może polegać na wysyłaniu plików cookie w odpowiedzi na żądania z tagów <img>, tagów <script> itd. Typowe zastosowania to m.in. piksele śledzące i personalizacja treści.

Dotyczy to też żądań zainicjowanych z JavaScriptu przez fetch lub XMLHttpRequest. Jeśli funkcja fetch() jest wywoływana z opcją credentials: 'include', jest to dobry znak, że w przypadku tych żądań pliki cookie mogą być oczekiwane. W przypadku XMLHttpRequest poszukaj instancji usługi withCredentials z ustawieniem true. To dobry znak, że pliki cookie mogą być od tych żądań zgodne z oczekiwaniami. Takie pliki cookie muszą być odpowiednio oznaczone, aby były uwzględniane w żądaniach z innych witryn.

Treści w komponencie WebView

Komponent WebView w aplikacji na danej platformie działa w przeglądarce, dlatego musisz sprawdzić, czy nie występują te same ograniczenia lub problemy. Jeśli na Androidzie w komponencie WebView działa Chrome, nowe ustawienia domyślne nie zostaną od razu zastosowane w Chrome 84. Pamiętaj jednak, że zamierzasz zastosować je w przyszłości, więc i tak musisz się do tego przygotować i przetestować. Dodatkowo Android zezwala aplikacjom na danej platformie na ustawianie plików cookie bezpośrednio przez interfejs API CookieManager. Podobnie jak w przypadku plików cookie ustawianych za pomocą nagłówków lub JavaScriptu, pamiętaj o umieszczeniu SameSite=None; Secure, jeśli są one przeznaczone do użytku w różnych witrynach.

Jak wdrożyć SameSite już dziś

W przypadku plików cookie, które są potrzebne tylko w kontekście własnym, w zależności od potrzeb oznacz je jako SameSite=Lax lub SameSite=Strict. Możesz też nie robić nic i pozwolić przeglądarce na wymuszenie stosowania domyślnych ustawień, ale wiąże się to z ryzykiem niespójności w działaniu różnych przeglądarek i potencjalnymi ostrzeżeniami w konsoli dotyczącymi każdego pliku cookie.

Set-Cookie: first_party_var=value; SameSite=Lax

Jeśli pliki cookie są potrzebne w kontekście innych firm, musisz oznaczyć je jako SameSite=None; Secure. Pamiętaj, że musisz używać obu atrybutów razem. Jeśli określisz None bez Secure, plik cookie zostanie odrzucony. Istnieją jednak pewne różnice w implementacjach przeglądarek, dlatego może być konieczne zastosowanie pewnych strategii łagodzących opisane poniżej w sekcji Obsługa niezgodnych klientów.

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

Obsługa niezgodnych klientów

Te zmiany dotyczące uwzględniania None i aktualizacji domyślnego działania są wciąż stosunkowo nowe, dlatego w przeglądarkach występują niespójności w sposobie obsługi tych zmian. Informacje o znanych obecnie problemach znajdziesz na stronie z aktualizacjami na chromium.org, ale nie wiemy, czy są one wyczerpujące. Nie jest to idealne rozwiązanie, jednak na etapie przejściowym możesz zastosować pewne obejścia. Ogólna zasada jest jednak taka, że niekompatybilne klienty traktuj jako przypadek szczególny. Nie twórz wyjątku dla przeglądarek stosujących nowsze reguły.

Pierwsza opcja to ustawienie zarówno nowych, jak i starych plików cookie:

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

Przeglądarki, które stosują nowsze działanie, dodają do pliku cookie wartość SameSite, natomiast inne przeglądarki mogą go ignorować lub nieprawidłowo ustawiać. Jednak te same przeglądarki ustawią plik cookie 3pcookie-legacy. Podczas przetwarzania uwzględnionych plików cookie witryna powinna najpierw sprawdzić, czy na stronie jest nowy plik cookie. Jeśli go nie znajdzie, a potem wrócić do starszego pliku cookie.

Poniższy przykład pokazuje, jak to zrobić w środowisku Node.js przy użyciu platformy Express i jej oprogramowania pośredniczącego cookie-parser.

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);

Wadą jest to, że wymaga to skonfigurowania zbędnych plików cookie na potrzeby wszystkich przeglądarek i wymaga wprowadzenia zmian zarówno w momencie konfigurowania, jak i odczytywania pliku cookie. Takie podejście powinno jednak obejmować wszystkie przeglądarki niezależnie od ich działania i zapewnić, że pliki cookie innych firm będą działać bez zmian.

W momencie wysyłania nagłówka Set-Cookie możesz też wybrać wykrycie klienta za pomocą ciągu klienta użytkownika. Zapoznaj się z listą niezgodnych klientów, a potem użyj odpowiedniej biblioteki dla swojej platformy, np. biblioteki ua-parser-js w Node.js. Lepiej znaleźć bibliotekę do obsługi wykrywania klientów użytkownika, bo najprawdopodobniej nie chcesz tworzyć takich wyrażeń samodzielnie.

Zaletą tego podejścia jest to, że wymaga ono tylko wprowadzenia jednej zmiany w momencie konfigurowania pliku cookie. Należy jednak pamiętać, że wychwytywanie klienta użytkownika jest z natury delikatne i może nie wychwycić wszystkich użytkowników, których dotyczy ten problem.

Obsługa SameSite=None w językach, bibliotekach i platformach

Większość języków i bibliotek obsługuje atrybut SameSite w przypadku plików cookie, jednak dodanie SameSite=None jest wciąż stosunkowo nowe, dlatego na razie może być konieczne obejście niektórych standardowych działań. Informacje na ten temat znajdziesz w repozytorium z przykładami SameSite na GitHubie.

Uzyskiwanie pomocy

Pliki cookie są wszędzie i rzadko zdarza się, by żadna witryna była w pełni weryfikowana, gdzie zostały skonfigurowane i używane – zwłaszcza po dodaniu do nich przypadków użycia pochodzących z różnych witryn. Gdy napotkasz problem, zapewne jest to pierwszy raz, gdy ktoś napotka go po raz pierwszy, więc skontaktuj się z nami: