29-07-2019 / Podcast

Jak działa SameSite cookie?

Wprowadzenie

W Internecie pojawiła się informacja iż już za niedługo możemy być świadkami końca błędów typu CSRF.

A to wszystko za sprawą ruchu firmy Google i potencjalnych zmianach, które mają pojawić się już za jakiś czas w przeglądarce Chrome.

Dzisiaj opowiem o mechanizmie SameSite cookie, którego celem jest ochrona przed atakami Cross Site Request Forgery.

Na początku wytłumaczę co to są ciasteczka i dlaczego są takie ważne w dzisiejszym Internecie.

Dalej parę słów o fladze httponly oraz secure.

Potem po krótce scharakteryzuje atak CSRF.

Jakie są jego konsekwencje oraz powody a także jakie obecnie metody stosuję się aby uniknąć tej podatności.

Na samym końcu dowiesz się jak działa samesite i jakie wartości może przyjmować.

Porozmawiamy także o kontrowersjach i problemach, które mogą pojawić się wraz z szeroką adaptacją tego standardu.

Jeżeli któryś z tych tematów jest Ci znany, w opisie do tego odcinka odnajdziesz sygnatury czasowe, które pozwolą Ci na przejście do interesującego Cię miejsca.

Podcast ten można również znaleźć na Spotify oraz Google i Apple Podcasts oraz Anchor.

Protokół HTTP

Zacznijmy od początku.

Protokół HTTP - czyli ten, którego używamy do przeglądania Internetu w przeglądarce jest bezstanowy.

Oznacza to, że serwer nie przechowuje informacji o wcześniejszych żądaniach.

Czyli każde wejście na inną podstronę tej samej witryny jest traktowane przez serwer jako nowe.

Aplikacja zatem nie może rozróżnić użytkowników i powiązać z nimi jakikolwiek informacji.

A to jest problematyczne, zwłaszcza w dzisiejszych czasach mediów społecznościowych, kiedy to informację dla nas przeznaczone są spersonalizowane.

To znaczy, większość witryn wyświetla nam zazwyczaj to co chcemy zobaczyć oraz czym jesteśmy zainteresowani.

Z tego też powodu serwer powinien wiedzieć, że my to my aby móc odpowiednio przetwarzać nasze żądania.

Jak działają ciasteczka

I tu do gry wchodzą ciasteczka, czyli małe pliki na dysku twardym użytkownika, które są przesyłane automatycznie przez przeglądarkę za każdym razem gdy wchodzimy na jakąkolwiek podstronę danej witryny.

Mechanizm działania jest prosty.

Każda strona może ustawić swoje ciasteczko.

Zazwyczaj zawiera ono jakiś losowy ciąg znaków wygenerowany przez serwer.

Witryna przechowuje informacje na temat ustawionych przez siebie ciasteczek oraz stanu użytkownika, który jest z nim powiązany.

Dzięki temu, jeżeli dla przykładu zalogujemy się na stronie - witryna wygeneruje dla nas nowe ciasteczko oraz powiąże je z naszym kontem użytkownika w serwisie.

Teraz, gdy przejdziemy na kolejną podstronę przeglądarka automatycznie, wraz z informacją o podstronie którą chcemy odwiedzie, doda również pasujące do danej domeny ciasteczko.

Serwer odczyta jego zawartość i na tej podstawie stwierdzi, ze jesteśmy zalogowanymi użytkownikami i posiadamy odpowiednie uprawnienia.

To właśnie dzięki ciasteczkom nie musimy za każdym razem podawać loginu i hasła do popularnych witryn za każdym razem gdy uruchamiamy naszą przeglądarkę.

Każde ciasteczko bowiem ma ustalony czas ważności, który informuje przeglądarkę czy wartość zapisana w danym ciasteczku jest jeszcze prawidłowa i powinna być wysłana razem z naszym żądaniem.

Flaga Secure

Jak wiemy Internet to szybko rozwijająca się dziedzina.

Z czasem okazało się, że coś co dla jednych jest błogosławieństwem - dla niektórych może być przekleństwem.

Przed chwilą powiedziałem bowiem, że ciasteczko jednoznacznie identyfikuje danego użytkownika.

Oznacza to, że jeżeli potencjalny atakujący przechwyci jego wartość - będzie mógł przesłać je do serwera podszywając się tym samym pod swoją ofiarę.

A to wszystko bez posiadania loginu i hasła danej osoby.

Mówimy tutaj o dawnych czasach, jeszcze przed tym aż szyfrowanie połączenia i używanie protokołu https stało się popularne.

Pamiętajmy bowiem, że protokół HTTP sam z siebie nie jest szyfrowany, to znaczy że wszystkie informacje przekazywane są w czystym tekście.

Jeżeli więc ktoś podsłuchuje nasze połączenie - może przejąć ciasteczka, które wysyłamy z każdym żądaniem.

A taka sytuacja nie jest tak rzadka jak mogło by się wydawać, zwłaszcza w dzisiejszym mobilnym świecie.

Wystarczy bowiem, że podłączymy się do otwartej sieci wifi w kawiarni albo na lotnisku.

Jeżeli używana przez nas witryna nie korzystała z szyfrowania, z łatwością można było podsłuchać nasze połączenie i podszyć się pod naszą osobę.

Z tego powodu wprowadzono flagę Secure.

Gdy ciasteczko zostało ustawione przez serwer wraz z tą flagą, przeglądarka wie - że takie ciasteczko może wysyłać jedynie przy pomocy protokołu https.

Dzięki temu, nawet jeżeli w którymś momencie odwiedzimy niebezpieczną wersję witryny przy pomocy protokołu http - nasze ciasteczko będzie bezpieczne.

To zabezpieczenie chroni nas więc w przypadku podsłuchiwania naszej transmisji.

Flaga HttpOnly

Ale w Internecie czai się więcej niebezpieczeństw.

Także takich, na których nie mamy większego wpływu.

O ile bowiem możemy nie korzystać z publicznych sieci wifi o tyle nie mamy większego wpływu na kod strony, której używamy na co dzień.

Jeżeli programiści popełnili na niej jakieś błędy bezpieczeństwa, nie bardzo mamy co z nimi zrobić.

Chodzi mi tutaj o atak XSS.

W największym skrócie polega on na wykonaniu nieautoryzowanego kodu JavaScript na danej stronie internetowej.

Ten kod nie został stworzony przez twórców witryny a przez potencjalnego atakującego, który wykorzystał błędy programistyczne, które pozwalają na umieszczenie zewnętrznego skryptu.

A taka sytuacja jest niebezpieczna.

Z poziomu kodu JavaScript mamy bowiem kontrole nad całą stronę internetową.

W tym do ciasteczek.

Wystarczy wiec, ze potencjalny atakujący umieści odpowiedni kod, który będzie kradł ciasteczka od użytkownika a następnie wysyłał je do serwera kontrolowanego przez przestępcę.

On to będzie mógł je ponownie wykorzystać do zalogowania się na skradzione konto i wykonania jakiejś akcji w imieniu ofiary.

Dlatego też wprowadzono kolejną flagę HttpOnly.

Ona to sprawia, że nie można odczytać wartości ciasteczka z poziomu kodu JavaScript.

Dzięki temu nawet jeżeli strona zawiera kod XSS, atakujący nie będzie mógł wykraść przy jego pomocy ciasteczka.

Wiemy już zatem jak wygląda historia ciasteczek oraz jakie dodatkowe metody wprowadzono, aby zabezpieczyć je przez pewnymi atakami.

Na czym polega CSRF

Na czym zatem polega atak CSRF?

Przeglądarka przechowuje listę ciasteczek wraz z domenami, które je ustawiły.

Podczas każdego żądania, sprawdza ona czy posiada ciasteczko powiązane z danym adresem.

Jeżeli ciasteczko istnieje, zostaje automatycznie dołączone do żądania wraz z innymi informacjami.

Dla nas - czyli użytkowników końcowych jest to wiec automatyczne i nie wymaga od nas żadnego działania.

Tylko, ze to ciasteczko wysyłane jest zawsze o ile tylko domena pasuje.

A to nie jest do końca takie dobre.

Dlaczego?

Ponieważ na stronach internetowych znajdują się formularze.

To właśnie dzięki nim możemy się logować, rejestrować czy też publikować komentarze.

Tylko, że formularze nie zawsze muszą wysyłać informację do tej samej domeny, na której się znajdują.

Można bowiem stworzyć formularz, który będzie wysyłał zapisane informację do domeny b umieszczając go równocześnie na domenie a.

To samo w sobie nie jest jeszcze wielkim problemem, tylko że podczas takiego przesyłania danych - przeglądarka automatycznie dołoży do naszych informacji ciasteczka, które pasują do domeny b.

A to jest już niebezpieczne.

Dlaczego?

Ponieważ formularze kontrolują więcej zachowań witryny niż nam się wydaje.

Przy pomocy formularzy możemy zmienić hasło, nasz adres email lub też usunąć konto w serwisie.

Przykład wykorzystania CSRF

Przykładowy atak wygląda zatem następująco.

Potencjalny atakujący tworzy odpowiedni formularz, w którym zawiera wszystkie informacje potrzebne do zmiany naszego adresu email w danym serwisie.

Następnie przekonuje nas do odwiedzenia swojej strony, na której znajduje się tak spreparowany formularz.

W momencie wejścia na witrynę - wykonuje się kod JavaScript, który automatycznie wysyła przygotowany wcześniej formularz do innej witryny.

Równocześnie przeglądarka dokleja do tego żądania pasujące ciasteczka.

Jeżeli zatem byliśmy już wcześniej zalogowani na podatnej witrynie, wraz z formularzem otrzyma ona nasze ciasteczko.

Na jego podstawie określi, ze my to my i zmieni w serwisie adres email powiązany z naszym kontem.

I to wszystko bez naszej interakcji i wiedzy.

Wystarczyły tylko, że weszliśmy na złośliwą stronę.

Większość stron posiada możliwość przypominania hasła, które zostało przez nas zapomniane.

Do tego celu używa się wiadomości email, która ma sprawdzić że my to my.

A ponieważ atakujący właśnie zmienił nasz adres, wiadomość o zmianie hasła trafi na kontrolowaną przez niego skrzynkę.

Dzięki temu jest w stanie uzyskać dostęp do naszego konta.

Prawda, że przerażające?

Sprawdzanie nagłówków Origin oraz Referer

Z tego też powodu twórcy witryn zaczęli się bronić przed tego rodzaju atakami.

Istnieje kilka różnych metod.

Pierwsza to wykorzystanie nagłówków Origin oraz Referer.

Są to informacje automatycznie dodawane przez przeglądarkę.

W nagłówku Origin znajduje się nazwa domeny, z której nastąpiło dane żądanie.

Referer zawiera tą samą informację, tylko że oprócz domeny znajduje się tam pełen adres podstrony, która zainicjalizowała żądanie.

Podstawowa technika zapobiegająca atakom CSRF polega zatem na sprawdzaniu tych nagłówków.

W przypadku prawidłowego użytkowania strony, będą one zawierały adres naszej domeny.

Jeżeli atakujący umieści formularz na osobnej domenie, nagłówki te będą zawierały właśnie jej adres.

Na tej podstawie można odrzucić tak spreparowane żądanie, stwierdzając iż najprawdopodobniej zostało sfałszowane.

Wykorzystywanie losowych tokenów

Inna metoda polega na używaniu losowych wartości.

Do każdego formularza, który jest wyświetlany na naszej stronie doklejane jest dodatkowe, ukryte pole, które zawiera losowo wygenerowany token.

Po wysłaniu dokumentu, serwer sprawdza zawartość tego pola porównując ją z wygenerowaną przez siebie wartością.

Jeżeli są one takie same - żądanie jest prawidłowe i może być obsługiwane dalej.

To zachowanie opiera się zatem na fakcie, że atakujący nie jest w stanie przewidzieć wartości tego pola.

O ile wie co jest potrzebne chociażby do zmiany emaila o tyle nie jest w stanie zgadnąć losowej wartości.

Co więcej, ta wartość jest inna dla każdego użytkownika i bardzo często zmienia się z każdym żądaniem.

No dobrze.

SameSite

Opisane tutaj metody muszą być jednak zaimplementowane po stronie serwera.

To znaczy że każda aplikacja, framework czy tez programista nie jako tworzą własną funkcję, która ma chronić przed tego rodzaju atakami.

A to rodzi wiele problemów.

Chociażby co w sytuacji, jeżeli programista zapomni o jednym formularzu w odległym miejscu witryny.

Jeżeli go nie sprawdza - jego strona jest podatna.

Po drugie brak tutaj pewnego rodzaju standaryzacji, wiele stron sprawdza to na wiele różnych sposobów.

I tu do gry wchodzi rewolucja czyli flaga SameSite.

Jest to wiec kolejna wartość, która może być ustalona podczas ustawiania ciasteczka.

Tym razem można wybrać 2 wartości: Lax oraz Strict.

SameSite=Strict

Zacznijmy od wytłumaczenia tej ostatniej czyli Strict.

Jeżeli ciasteczko ustawione jest właśnie z tą flagą, przeglądarka nie dołączy takiego ciasteczka do zadania, które pochodzi z innej domeny.

Jest to wiec najprostszy z możliwych pomysłów, które rozwiązuje cały nasz problem.

Żądanie pochodzi z innej domeny - preclarka nie dołączy ciasteczka automatycznie.

Serwer nic nie musi sprawdzać, nie ma potrzeby doklejania dodatkowych losowych wartości.

Brzmi świetnie, ale jest jedno ale.

Przeglądarka decyduje czy dołączyć ciasteczko bazując jedynie na pochodzeniu zapytania.

I tutaj dochodzimy do kluczowego wyjątku, który jest spotykany w Internecie niemal na każdym kroku.

Mowa bowiem o odnośnikach czyli hiperłączach, dzięki którym nawigujemy z jednej witryny na drugą.

Taki odnośnik tworzony jest przy pomocy tagu a href.

Z punktu widzenia przeglądarki jednak, jego klikniecie to nic innego jak wykonanie żądania do witryny, której adres znajduje się w tagu href.

Wszystko działa OK, jeżeli przemieszczamy się jedynie w obrębie jednej domeny.

Jeżeli jednak nasza domena wskazuje na jakąś inną stronę, żądanie zostanie wysłane do zewnętrznej domeny.

Nie zgodzi się więc pochodzenie zapytania, origin bowiem wskazuje na naszą domenę.

Przez to przeglądarka nie dołączy do tego żądania ciasteczka, nawet jeżeli użytkownik jest zalogowany.

A to może rodzić dziwne zachowania z punktu widzenia użyteczności.

Co przestanie działać?

Rozpatrzmy to na przykładzie.

Jesteśmy zalogowanymi użytkownikami Facebooka.

Korzystamy z niego na codzienna, praktycznie co chwile dlatego nigdy nie wylosowujemy się ze swojego konta.

Przeglądamy stronę sklepu internetowego, który zawiera odnośnik do grupy na Facebooku.

Klikamy w niego i zamiast treści grupy, Facebook prosi nas o zalogowanie.

Stało się tak, ponieważ kliknięcie w link zainicjalizowało żądanie do domeny facebook.com, a ponieważ używamy flagi Samesite z wartością strict - wartości żądanej domeny oraz domeny z której pochodziło żądanie różniły się od siebie.

Przez co przeglądarka nie dołączyła ciasteczka, pomimo tego iż je posiadała.

Ciasteczka a prywatność

Właśnie z tego powodu, niektórzy mogą uznać za stosowne używanie wartości Samesite=Lax

Możesz odnieść złudne wrażenie, że wystarczyło tutaj pozwolić przeglądarce na dołączanie ciasteczek, z różnych wartości origin jeżeli wykonywane jest żądanie GET.

Ale sprawa jest nieco bardziej skomplikowana.

W standardzie bowiem oprócz bezpieczeństwa postanowiono również uwzględnić prywatność użytkownika.

O co chodzi?

Wiemy, że ciasteczka służą do identyfikacji użytkownika.

Ale mogą także służyć do śledzenia jego poczynań w Internecie.

Względnie prosto jest to wytłumaczyć na przykładzie przycisku Polub to z Facebooka.

Bardzo wiele stron umieszcza kod odpowiedzialny za tą funkcjonalność na swojej stronie.

Wtedy to, kiedy użytkownik odwiedza naszą witrynę, równocześnie wysyła żądanie do serwerów Facebooka w celu załadowania kodu guzika Like.

Jeżeli jesteśmy zalogowani, razem z tym żądaniem - przeglądarka przesyła również nasze Facebookowe ciasteczko.

Dzięki temu serwis wie jakie witryny odwiedzamy.

A ponieważ bardzo dużo stron posiada taki guzik, można w ten sposób śledzić użytkownika.

Facebook bowiem za każdym razem otrzymuje żądanie o kod przycisku Like wraz z naszym ciasteczkiem oraz wartością origin.

Na tej podstawie może określić co przeglądamy.

SameSite=Lax

I tutaj do gry wchodzi flaga SameSite.

Stwierdzono bowiem, że w wersji Lax nie wystarczy jedynie, że przeglądarka wysyła żądanie GET do zewnętrznego serwera.

Aby ciasteczko zostało dołączone pomimo braku zgodności, żądanie takie musi doprowadzić do zmiany adresu URL w przeglądarce.

W specyfikacji określono to mianem top-level navigation.

W przypadku odnośników a href – po ich kliknięciu - domena zmiana się w pasku adresu - wszak przechodzimy pod inny adres.

Ale kod przycisku Lubię to, pobierany jest przez przeglądarkę w tle - tak samo jak chociażby pliki graficzne.

A takie żądania nie zmieniają pasku adresu, stąd też nie będą do nich dołączane ciasteczka w przypadku flagi samesite lax.

W ten sposób standard może zapewnić dodatkową prywatność, przed śledzącymi ciasteczkami używanymi przez wiele korporacji.

Warto tu jeszcze dopowiedzieć, że za bezpieczne metody HTTP uznano także metody GET, HEAD oraz TRACE.

Koniec błędów CSRF?

Wiem zatem jak działa nowy protokół.

Tylko, że to nic nowego.

Chrome posiada obsługę tegoż protokołu zaimplementowaną już od wersji 51.

Teoretycznie twórcy witryn mogli wiec korzystać z tego dodatkowego zabezpieczenia już od ponad 3 lat.

Rewolucją, są natomiast plany - aby włączyć ciasteczka SameSite=Lax automatycznie dla wszystkich domen w jednej z kolejnych wersji Chroma.

Oznaczało by to że programiście nie musieliby zmieniać swoich programów.

Chrome po prostu traktował by wszystkie ciasteczka bez tej flagi jako takie z flagą samesite z wartością lax.

A to już spora zmiana.

Z jednej strony może to pomóc pozbyć się palącego problemu jakim jest CSRF.

Z drugiej jednak strony podnoszą się głosy, iż cała akcja skierowana jest na duże firmy marketingowe, które w ten sposób stracą możliwość analizowania ruchu użytkownika.

Minusy rozwiązania

Na koniec warto również powiedzieć, iż rozwiązanie to nie jest idealne i w niektórych, specyficznych przypadkach można je ominąć.

Formularze bowiem mogą wysyłać dane również przy pomocy metody GET.

W takich wypadkach dodatkowa flaga nie pomoże, ponieważ metoda ta jest uznawana za bezpieczną a wysłanie formularza prowadzi do zmiany paska adresu.

Jeżeli więc jesteś programistą, w swojej aplikacji powinieneś pozwalać na przesyłanie danych jedynie w postaci metody POST.

W innym wypadku, żądanie powinno być odrzucane ponieważ może być zfałszowane.

Twórcy flagi przyjęli bowiem, że na stronach wszystkie akcję które powodują jakąś zmianę w aplikacji winny być wykonywane przy pomocy metody POST.

A na świecie zapewne znajdzie się wiele internetowych aplikacji, które zapisują dane przy pomocy metody GET.

A co wy sądzicie o tej zmianie?

Czy to krok w dobrą stronę?

1 2 3 4 5