Gdy użytkownik jest już zalogowany, identyfikator sesji jest tymczasowo równoważny najsilniejszej metodzie uwierzytelnienia, jakiej użyła aplikacja: czy było to hasło, kod jednorazowy, certyfikat klienta, karta chipowa czy odcisk palca. Jeśli atakujący może odgadnąć, przechwycić albo narzucić taki identyfikator, staje się tym użytkownikiem, a formularz logowania w ogóle nie wchodzi w grę. Testowanie sesji oznacza więc testowanie samego ID, ciasteczka, które go przenosi, oraz tego, co serwer z nim robi przy logowaniu, po okresie bezczynności i przy wylogowaniu.
Ta checklista opiera się na OWASP Session Management Cheat Sheet oraz RFC 6265, czyli specyfikacji cookies.
Sam identyfikator sesji
Zacznij od tego, jak powstaje ID. Cheat sheet wymaga co najmniej 64 bitów entropii z kryptograficznie bezpiecznego generatora liczb losowych. Przy takiej długości szacuje czas odgadnięcia poprawnego ID na około 585 lat, przy założeniu 10 000 prób na sekundę i 100 000 jednocześnie aktywnych sesji. Jeśli generujesz własne ID zamiast korzystać z mechanizmu frameworka, zaleca co najmniej 128 bitów i unikalną wartość dla każdej sesji.
Szukaj stałych lub przewidywalnych fragmentów. 16-znakowy identyfikator szesnastkowy, w którym połowa jest stała, ma tylko 32 bity entropii, a to za mało. Wartość nie powinna też nic znaczyć dla klienta: bez ID użytkownika, roli czy adresu e-mail w środku. Taki stan trzymaj po stronie serwera.
Sprawdź też nazwę. Domyślne nazwy, takie jak PHPSESSID, JSESSIONID, CFID/CFTOKEN i ASP.NET_SessionId, zdradzają atakującemu, z jakiego stosu korzystasz. Cheat sheet sugeruje ogólną nazwę, np. id.
Nigdy nie akceptuj ID w adresie URL. Identyfikatory przekazywane w URL wyciekają przez linki, logi, historię przeglądarki, zakładki, nagłówek Referer i wyszukiwarki, a do tego ułatwiają fixation.
Jeśli w Twoim modelu zagrożeń mieści się dostęp do odczytu magazynu sesji, surowe tokeny są ryzykiem. Cheat sheet opisuje rozwiązanie z podziałem: cookie niesie identyfikator i tajny verifier, a serwer przechowuje identyfikator oraz skrót SHA-256 z verifiera, porównywany w stałym czasie. Sam identyfikator nigdy nie jest akceptowany.
Atrybuty cookies
RFC 6265 definiuje dla nagłówka Set-Cookie następujące atrybuty: Expires, Max-Age, Domain, Path, Secure i HttpOnly.
Secureoznacza cookie jako przeznaczone wyłącznie dla bezpiecznych połączeń. RFC ostrzega, że nie daje to integralności wobec aktywnego atakującego w sieci, więc nie traktuj go jako ochrony przed nim.HttpOnlypowinien być ustawiony na każdym cookie sesyjnym. Potwierdź obecność flagi w narzędziach deweloperskich przeglądarki.DomainiPathokreślają zakres. Utrzymuj oba nie szersze, niż potrzebuje aplikacja.ExpiresiMax-Agemówią przeglądarce, jak długo przechowywać cookie. Nie używaj ich jako swojego timeoutu.
Pozostałe nagłówki odpowiedzi sprawdzisz za pomocą naszego narzędzia do analizy nagłówków bezpieczeństwa.
Logowanie, timeouty i wylogowanie
Na ataki typu fixation liczą te przypadki, w których identyfikator sesji, który przeglądarka miała przed logowaniem, zostaje po nim bez zmian. Wydaj nowe ID w momencie uwierzytelnienia, aby poprzednie przestało być ważne.
Timeouty wymagają dwóch limitów. Idle timeout (limit bezczynności) kończy sesje, z których nikt nie korzysta. Absolute timeout (limit bezwzględny) kończy sesje, które są aktywne bez końca, co ogranicza czas, przez jaki skradzione ID pozostaje użyteczne. Zapisz konkretne wartości, ustaw krótsze dla administracji i płatności oraz egzekwuj je po stronie serwera, sprawdzając zapisany rekord sesji, a nie datę wygaśnięcia cookie.
Wylogowanie musi niszczyć sesję po stronie serwera. Usunięcie cookie w przeglądarce nie wystarcza, ponieważ to identyfikator jest poświadczeniem: każdy, kto skopiował go wcześniej, nadal może go wysłać. Po wylogowaniu stare ID nie powinno odpowiadać niczemu. Cheat sheet ma też sekcję o cache'owaniu treści webowych i Clear-Site-Data, którą warto przeczytać, by wiedzieć, co przeglądarka zachowuje po wylogowaniu.
Tam, gdzie to możliwe, korzystaj z wbudowanej obsługi sesji we frameworku. Cheat sheet zauważa, że te implementacje miały podatności, więc używaj najnowszej wersji i przejrzyj ustawienia domyślne.
Co testować
- Przechwyć cookie przed logowaniem i po nim. Pierwsze żądanie musi faktycznie ustawić cookie sesyjne, więc sprawdź, że
before.txtnie jest pusty. Dane logowania trzymaj w pliku (creds.txtz zawartościąuser=test&pass=...), aby nie trafiły do historii powłoki. Oba ID muszą się różnić.
curl -i -c before.txt https://app.example/login curl -i -b before.txt -c after.txt -d @creds.txt https://app.example/login
- Wyloguj się z użyciem uwierzytelnionego cookie, a następnie odtwórz starą wartość, wziętą z ostatniej kolumny
after.txt. Musi zostać odrzucona. Jeśli wylogowanie odbywa się przez POST, dodaj-d ''do pierwszego polecenia.
curl -i -b after.txt https://app.example/logout curl -i -b 'id=VALUE_FROM_AFTER_TXT' https://app.example/account
- Zaloguj się, pozostań bezczynny dłużej niż wynosi idle timeout, a potem wyślij żądanie. Aplikacja musi ponownie wymagać uwierzytelnienia.
- Utrzymuj sesję aktywną ponad absolute timeout. Mimo to musi się zakończyć.
- Sprawdź
Set-Cookiew odpowiedzi na logowanie pod kątemSecure,HttpOnlyorazDomainiPathnie szerszych, niż to potrzebne. - Zbierz kilkaset ID i porównaj je. Stałe segmenty i kolejne wartości to ustalenia. Porównaj nazwę cookie z domyślnymi nazwami frameworków podanymi wyżej.
- Przeszukaj aplikację, logi i linki pod kątem identyfikatorów sesji w adresach URL.
Zgłaszaj ustalenia względem OWASP ASVS z podaniem wersji: v5.0.0-<chapter>.<section>.<requirement>. ASVS 5.0.0 opublikowano 30 maja 2025 r., a jego wymagania są dostępne w formacie CSV. Dodaj do arkusza testów kolumnę z identyfikatorem dla każdego testu, aby niezaliczony test wyglądał jak ustalenie powołujące się na swoje wymaganie.
Od czego zacząć
- Najpierw uruchom testy 1 i 2 na środowisku staging: porównanie ID przed logowaniem i po nim, a potem odtworzenie starego ID po wylogowaniu.
- Przechwyć nagłówek
Set-Cookiedla swojego cookie sesyjnego i popraw brakujące lub zbyt szerokie atrybuty. - Sprawdź, jak generowane są ID. Jeśli zbudowano własny generator, przejdź na ten z frameworka albo potwierdź, że używa bezpiecznego źródła losowości i co najmniej 128 bitów.
- Zapisz wartości idle i absolute timeout, egzekwuj je po stronie serwera i dodaj testy, które zawiodą, jeśli ktoś je usunie.
- Spraw, aby wylogowanie usuwało rekord sesji po stronie serwera, i dodaj testy odtworzenia ID do swojego zestawu testów regresji.
