flagi ciasteczek
| Po angielsku | cookie security attributes (HttpOnly, Secure, SameSite) |
|---|---|
| Którą formą pisać | obie formy Obie formy są w obiegu. Przy pierwszym wystąpieniu pisz „polski termin (english term)”, dalej sam polski. |
| Inne formy | flagi cookie · atrybuty ciasteczek · flaga HttpOnly · flaga Secure · flaga SameSite · atrybut SameSite |
| Kategoria | Strony WWW, WordPress i hosting |
Flagi ciasteczek (cookie security attributes) to atrybuty dopisywane przez serwer do nagłówka Set-Cookie, które ograniczają, kiedy i komu przeglądarka udostępnia ciasteczko. Trzy najważniejsze to HttpOnly, Secure i SameSite: pierwsza odcina ciasteczko od JavaScriptu, druga pozwala wysyłać je tylko po HTTPS, trzecia ogranicza wysyłanie przy żądaniach z innych witryn [1]. Flagi nie szyfrują zawartości ciasteczka. Zmniejszają liczbę dróg, którymi może ono wyciec albo zostać nadużyte, i dlatego OWASP zalicza je do podstaw zarządzania sesją [3].
Jak działa
Ciasteczko powstaje, gdy serwer wysyła nagłówek Set-Cookie z nazwą, wartością i listą atrybutów. Przeglądarka zapamiętuje je razem z atrybutami i przy każdym kolejnym żądaniu sama decyduje, czy dołączyć je w nagłówku Cookie. Flagi są więc instrukcją dla przeglądarki, a nie mechanizmem po stronie serwera. Przykładowe ciasteczko sesji z kompletem flag wygląda tak:
Set-Cookie: __Host-sesja=abc123; Path=/; Secure; HttpOnly; SameSite=Lax
Schemat poniżej pokazuje, jak flagi działają w praktyce: serwer ustawia ciasteczko, przeglądarka odsyła je tylko po HTTPS, a skrypt uruchomiony na stronie nie może go odczytać.
Rodzaje
Specyfikacja RFC 6265 z kwietnia 2011 roku opisuje atrybuty Secure i HttpOnly [2]. Atrybut SameSite i prefiksy nazw dokumentuje MDN jako elementy obsługiwane przez współczesne przeglądarki [1].
| Flaga | Co robi | Przed czym chroni |
|---|---|---|
HttpOnly | ukrywa ciasteczko przed API skryptów [2] | kradzież sesji przez XSS [1] |
Secure | wysyłka tylko przez https: [1] | podsłuch w sieci (MITM) [1] |
SameSite=Strict | tylko żądania z tej samej witryny [1] | CSRF, obrona warstwowa [3] |
SameSite=Lax | także nawigacja z innej witryny metodą bezpieczną [1] | CSRF, obrona warstwowa [3] |
SameSite=None | wysyłka zawsze, wymaga Secure [1] | nie chroni |
HttpOnly. Według RFC 6265 atrybut każe przeglądarce pomijać ciasteczko, gdy udostępnia ciasteczka przez interfejsy inne niż HTTP, na przykład przez API dla skryptów [2]. MDN zaznacza, że takie ciasteczko nadal jest dołączane do żądań wysyłanych przez JavaScript, na przykład przez fetch() [1].
Secure. Ciasteczko z tym atrybutem trafia do serwera tylko w żądaniach po https:, z wyjątkiem adresu localhost [1]. Strona działająca po http: nie może ustawić ciasteczka z atrybutem Secure [1].
SameSite. Wartość Strict wysyła ciasteczko tylko przy żądaniach z witryny, która je ustawiła. Lax dopuszcza dodatkowo żądania z innych witryn, jeśli są nawigacją najwyższego poziomu i używają bezpiecznej metody. None wysyła ciasteczko zawsze i wymaga flagi Secure [1]. Część przeglądarek przyjmuje Lax jako wartość domyślną, gdy atrybutu brak [1].
Zakres i prefiksy. Atrybuty Domain i Path określają, do których hostów i ścieżek ciasteczko jest wysyłane; ustawienie Domain udostępnia je także wszystkim subdomenom [1]. Nazwa zaczynająca się od __Host- wymaga flagi Secure, braku atrybutu Domain i ścieżki /, dzięki czemu ciasteczko trafia tylko do hosta, który je ustawił [1]. OWASP zaleca ten prefiks dla identyfikatorów sesji [3].
W WordPressie
WordPress ustawia ciasteczka logowania funkcją wp_set_auth_cookie(). Tworzy ona ciasteczko uwierzytelniające (w wariancie zwykłym albo bezpiecznym) oraz ciasteczko LOGGED_IN_COOKIE [6]. Wszystkie wywołania setcookie() w tej funkcji mają parametr httponly ustawiony na true [6]. O fladze Secure decyduje parametr $secure; gdy nie jest podany, funkcja przyjmuje wynik is_ssl(), czyli sprawdza, czy bieżące żądanie przyszło po HTTPS [6]. Filtry secure_auth_cookie i secure_logged_in_cookie pozwalają zmienić tę decyzję dla obu rodzajów ciasteczek [6].
Czas życia zależy od pola „Zapamiętaj mnie”. Po jego zaznaczeniu ciasteczko obowiązuje 14 dni, z możliwością zmiany filtrem auth_cookie_expiration; bez niego jest ciasteczkiem sesji przeglądarki [6]. W wywołaniach setcookie() w tej funkcji nie ma atrybutu SameSite [6], więc o wysyłce przy żądaniach z innych witryn decyduje domyślne zachowanie przeglądarki. Przed CSRF (Cross-Site Request Forgery) w panelu WordPress broni się osobno, tokenami nonce.
Wartość ciasteczka logowania jest podpisana kluczami z pliku wp-config.php; zob. klucze bezpieczeństwa i sole. Flagi nie zastępują tego podpisu, tylko utrudniają kradzież gotowego ciasteczka. Wtyczki, które zakładają własne ciasteczka, same ustawiają ich atrybuty i nie dziedziczą ustawień rdzenia.
Zagrożenia i skutki
Brak flag jest opisany w katalogu CWE jako dwie osobne słabości. CWE-1004 dotyczy ciasteczka z danymi wrażliwymi bez HttpOnly: skrypt po stronie klienta może je odczytać, a gdy jest to ciasteczko uwierzytelniające, atakujący może ukraść identyfikator sesji i podszyć się pod użytkownika [4]. MITRE podaje przykłady takich błędów w realnym oprogramowaniu, między innymi CVE-2024-47833 i CVE-2022-24045 [4]. CWE-614 dotyczy braku Secure w sesji HTTPS: przeglądarka może wtedy wysłać ciasteczko otwartym tekstem po HTTP [5].
- Przejęcie sesji przez odczyt tokenu sesyjnego skryptem wstrzykniętym przez XSS (Cross-Site Scripting).
- Podsłuch ciasteczka w niezaszyfrowanym połączeniu, typowy dla ataku man-in-the-middle (MITM) w publicznej sieci Wi-Fi.
- Żądania wykonywane w imieniu zalogowanego użytkownika z obcej witryny, gdy ciasteczko jest wysyłane bez ograniczeń SameSite.
Flagi mają granice. Sekurak podkreśla, że HttpOnly daje tylko częściową ochronę: atakujący z działającym XSS nie musi kraść ciasteczka, bo może zmienić wygląd strony albo wstawić keylogger [7]. RFC 6265 ostrzega, że Secure chroni poufność ciasteczka, ale nie jego integralność: aktywny atakujący w sieci może nadpisać ciasteczko Secure z kanału niezabezpieczonego [2].
Dobre praktyki
OWASP zaleca dla ciasteczek sesji komplet flag: Secure, HttpOnly i SameSite w trybie Strict albo Lax [3]. SameSite traktuje jako obronę warstwową przed CSRF, która nie zastępuje tokenów CSRF [3]. Zakres ciasteczka powinien być wąski: bez szerokiego atrybutu Domain i z Path ograniczonym do katalogu aplikacji [3]. Dla sesji OWASP zaleca ciasteczka nietrwałe, które znikają po zamknięciu przeglądarki [3].
- Cała witryna po HTTPS z ważnym certyfikatem SSL/TLS, bez mixed content. Flaga Secure ma sens tylko wtedy, gdy strona w ogóle działa po TLS.
- Nagłówek HSTS (HTTP Strict Transport Security), który zmusza przeglądarkę do HTTPS jeszcze przed wysłaniem pierwszego żądania; należy on do nagłówków bezpieczeństwa HTTP.
- Przegląd ciasteczek ustawianych przez wtyczki, bo ich atrybuty zależą od autora wtyczki, a nie od rdzenia.
- Oddzielenie kwestii technicznych od prawnych: flagi nie mają związku z zgodą na pliki cookie, która dotyczy celu przetwarzania, a nie sposobu wysyłki.
Przypisy
7- [1] Set-Cookie header · MDN Web Docs
- [2] RFC 6265: HTTP State Management Mechanism · IETF
- [3] Session Management Cheat Sheet · OWASP
- [4] CWE-1004: Sensitive Cookie Without 'HttpOnly' Flag · MITRE
- [5] CWE-614: Sensitive Cookie in HTTPS Session Without 'Secure' Attribute · MITRE
- [6] wp_set_auth_cookie() — Code Reference · WordPress.org
- [7] Flaga cookie – HttpOnly · Sekurak