Wpis z mikrobloga

Wczoraj pisałem o liście aktywnych sesji konta ( https://wykop.pl/wpis/76151855/czy-wy-jestescie-normalni-na-tym-wykopie-ktory-sys ). Spotkało się to z niemałym odzewem. Część osób zadała pytania, co z tym faktem zrobić i czy to coś poważnego. Z tego powodu trochę poszperałem i moja sugestia jest następująca - absolutnie nic z tym nie zrobicie, a jeśli będziecie, to by nic nie dało (jak mawiał Pudzian)

TLDR: Lista aktywnych sesji tak naprawdę nią nie jest i usuwanie czegokolwiek z niej absolutnie NIC nie zmienia.

Poniżej opis dla ciekawych, jak to w rzeczywistości działa. Postaram się to opisać w dużym uproszczeniu, aby wiedza techniczna nie była wymagana do zrozumienia całego procesu.

Kiedyś bardzo częstą praktyką było to, że użytkownik, po zalogowaniu, otrzymywał ciąg znaków, który reprezentuje aktywną sesję. System zapisywał sobie, że np. ABCDEFGH oznacza, że inyourbrain zalogował się o 11:46, a jego sesja jest ważna 24 godziny. Z każdą aktywnością czas aktywnej sesji mógł być podbijany (np. 24h od ostatniej akcji). Jeśli użytkownik się wylogował lub czas ten minął, to taki zapis uległ usunięciu. W takiej sytuacji, gdyby ktoś skorzystał z ciągu ABCDEFGH, to system po prostu nie posiada takiego zapisu i wymaga od użytkownika ponownego zalogowania się.

Z czasem (wraz z rozwojem rozproszonych systemów jak mikroserwisy) wprowadzono inną koncepcję (która m.in. jest wykorzystywana na wykopie), która zakłada, że serwer uwierzytelniający wystawi token (coś jak urząd wystawiający dokument tożsamości), w którym będą zapisane wszelkie informacje np. data wygaśnięcia, dostępne uprawnienia czy chociażby nazwę uzytkownika. Dzięki temu serwery nie mają potrzeby ciągłego zapisywania aktywnych sesji (bo ich de facto nie ma) i aktualizacji bazy danych, gdyż przeglądarka przesyła wspomniany token do serwera i serwer jedynie weryfikuje jego czas wygaśnięnia i to, czy w ogóle token jest legitny (czytaj utworzony przez zaufane źródło).

Rozwiązanie to ma dwa minusy - serwery nie przechowują, ile takich tokenów zostało wystawionych, więc z perspektywy użytkownika nie da się zakończyć aktywnych sesji (gdyż w tej sytuacji coś takiego w ogóle nie istnieje). "Sesja" po prostu wygaśnie wraz z czasem wygaśnięcia tokenu. @Pasterz30 słusznie zwrócił uwagę, że na Wykopie czas życia takiego tokenu wynosi 24 godziny. Z potrzeb biznesowych ludzie w IT zaczęli łączyć te dwie rzeczy - przesyłać dane za pomocą tokenów, jednocześnie przechwoując o nich informacje, by w razie czego móc je "zdezaktywować". Właśnie coś takiego jest na Wykopie. Tak, aby użytkownik mógł podejrzeć, na ilu urządzeniach jest zalogowany i taką "sesję" zakończyć.

Rozwiązanie z "tokenami" samo w sobie byłoby o tyle niewygodne, że wymagałoby od użytkowników codziennego ponownego logowania się, gdy token wygaśnie. Z pomocą przychodzi tutaj coś takiego jak "refresh token", który jest de facto taką przepustką umożliwiającą wygenerowanie następnego tokenu. Czyli token jest takim "dokumentem tożsamośći", a "refresh token" jest po prostu umożliwieniem wygenerowania kolejnego bez konieczności logowania się. Refresh token też ma swój czas wygaśnięcia i jest on dłuższy niż sam token (co jest logiczne).

I tutaj zaczyna się najciekawsze. Usunięcie wpisu z "aktywnych sesji" rzeczywiście powoduje unieważnienie danego tokenu. Jednakże użytkownik w przeglądarce ma zapisany ten "refresh token", który pozwala mu wygenerować nowy. Rozumiecie? To tak jakby policja Wam zatrzymała dowód rejestracyjny samochodu, po czym zwracacie się do urzędu o wystawienie nowego dowodu, a urząd mówi "Spoko, nie ma problemu, korzystaj z nowego dowodu". Tak właśnie działa to na Wykopie.

W systemach IT przyjęło się, by czasy trwania "tokenów" były w miarę krótkie. O ile sam "token" ma ważność 24 godziny (można to łatwo sprawdzić), o tyle refresh token jest dla mnie zagadką. Skorzystałem dzisiaj z urządzenia, na którym nie korzystałem z wykopu przez 3 tygodnie i... nie wylogowało mnie, a refresh token umożliwił wygenerowanie nowego. Z perspektywy bezpieczeństwa IT jest to wręcz karygodne.

W połączeniu tych 2 rzeczy - jeśli zdarzy się Wam gdzieś zalogować i zapomnieć o wylogowaniu, to ogarnięta osoba po prostu przejmie sobie Wasze konto na stałe, a Wy nic z tym nie zrobicie. Na szczęście nikt normalny nie loguje się na Wykop na nieswoich urządzeniach, prawda?

Lista aktywnych sesji na Wykopie nie dość, że wygląda źle (bo daje złudne wrażenie, że aktywnych sesji są tysiące), to do tego po prostu nie działa, ponieważ usunięcie wpisu dezaktywuje jedynie token, a refresh token umożliwia wygenerowanie nowego tokenu. Możecie zrobić prosty test - zalogujcie się na dwóch urządzeniach. Usuńcie wszystkie najnowsze wpisy korzystając z jednego urządzenia. Później odświeżcie stronę i zobaczcie, czy Was wylogowało. Dla leniwych - nie, nie wyloguje.

@m__b olewasz temat od miesięcy, gdy po telewizji biegasz jako "ekspert IT". Tutaj muszę wspomnieć, że @siedze-na-antresoli
siedze-na-antresoli pisał już o tym w styczniu https://wykop.pl/wpis/74728413/matko-bosko-po-kiego-grzyba-wykop-po-stronie-serwe

#programowanie #programista15k #security #wykop
  • 18
  • Odpowiedz
@inyourbrain: czy usuwając "sesję", czyli access token, da się po stronie serwera usunąć odpowiadający mu refresh token?

W sensie, że trzeba po stronie serwera trzymać access token + refresh token, ale czy jest jakieś inne rozwiązanie problemu?
  • Odpowiedz
  • 1
@NieBendePrasowac: Czysto w teorii, to Authorization Server powinien być bezstanowy, czyli nie powinien przechowywać tokenów w ogóle. Tylko wtedy nie ma mowy o "sesjach" i ich wygaszaniu. Główną ideą była możliwość zdecentralizowania uwierzytelniania. Bawienie się w przechowywanie tokenów to takie "zjeść ciastko i mieć ciastko". W tym przypadku, jak widzisz, samo przechowywanie access tokenów i nie respektowanie ich, gdy zostaną "usunięte", nie ma absolutnie żadnego sensu. Refresh token w tym przypadku
  • Odpowiedz
@inyourbrain: zaraz dostaniesz weryfikację konta i będziesz musiał podać mail oraz numer telefonu, czy aby nie jesteś botem, bo pchasz się w multikonto kolego, za to jak przekażesz maila oraz numer wykopowi oraz ich 830 partnerom, to na pewno te dane będą bezpieczne.
  • Odpowiedz
@inyourbrain czy ktos w ogole zweryfikowal czym sa te sesje na tej stronie? Moze to zwykla lista logowan. Kiedys wykop stal full na PHP i te sesje faktycznie mogly sobie lezec po stronie serwera i byc utrzymywane ale teraz juz to jest ogarniane fully za pomoca JWT od wykop 2.0
  • Odpowiedz
  • 0
@Pasterz30: Najprawdopodobniej to stary śmietnik, który właśnie jest listą logowań. Nowe wpisy tam się pojawiają za każdym razem, gdy nowy token zostanie wygenerowany. Po prostu źle to wygląda, a usuwanie i tak nie działa. Na wygaśnięcie refresh tokenu też nie ma co liczyć
  • Odpowiedz
@inyourbrain no to powinni to #!$%@? albo zmienic nazwe z „aktywne sesje” na „ostatnie logowania” i zamiast IP dac UserAgenta zeby to tak powaznie nie wygladalo. Zadnego security zagrozenia tu nie ma
  • Odpowiedz
  • 0
@Pasterz30: W samej tej liście nie, ale zwróciłeś uwagę na to, że refresh token jest zapewne ważny co najmniej miesiąc, co jest wręcz karygodne? Pod ręką miałem taki, który był wygenerowany 3 tygodnie temu i pozwolił mi na stworzenie nowego access tokenu.
  • Odpowiedz
@inyourbrain: czas zycia refresh tokena moze wynosic nawet kilka miesiecy i nie jest to specjalnie problematyczne z kilku powodow:

1. Refresh token rzadziej jest przesylany miedzy klientem a serwerem, wiec jego przechwycenie jest trudniejsze
2. Nawet jak ktos przechwyci taki dluzo zyjacy refresh token to do odswiezenia access tokena potrzebna jest jego stara instancja. Zwykle systemy maja rozne okna czasowe ktore pozwalaja refresh tokenowi odnowic access tokena. Jezeli stary access token
  • Odpowiedz
Bawienie się w przechowywanie tokenów to takie "zjeść ciastko i mieć ciastko".


@inyourbrain: w teorii to wiem, zastanawiam się jak sensownie taki problem (JWT zapisany po stronie serwera) rozwiązać.

Usunięcie wpisu z "aktywnych sesji" rzeczywiście powoduje unieważnienie danego tokenu.


@inyourbrain: na czym polega to unieważnienie tokenu? Nie możesz zmienić expiry date dla raz wygenerowanego tokenu, co najwyżej usunąć go z listy "sesji". Jeśli przy wylogowaniu samo usunięcie tokenu z przeglądarki
  • Odpowiedz
W samej tej liście nie, ale zwróciłeś uwagę na to, że refresh token jest zapewne ważny co najmniej miesiąc, co jest wręcz karygodne?


@inyourbrain: nie zgodzę się. Refresh token może mieć ważność i 90 dni. Często to się stosuje w aplikacjach mobilnych. Wiele aplikacji nie wyloguje Cię jeśli nie używasz jej np przez miesiąc.

To co jest ważne to aby prawidłowo używać refresh token rotation, czyli aby za każdym razem
  • Odpowiedz
Usuńcie wszystkie najnowsze wpisy korzystając z jednego urządzenia. Później odświeżcie stronę i zobaczcie, czy Was wylogowało. Dla leniwych - nie, nie wyloguje.

@inyourbrain: no mnie wylogowało
  • Odpowiedz
Nawet jak ktos przechwyci taki dluzo zyjacy refresh token to do odswiezenia access tokena potrzebna jest jego stara instancja.


@Pasterz30: Stara instancja access tokena? A nigdy w życiu, chyba że to jakaś chałupnicza implementacja. Specyfikacja OIDC/OAuth nic takiego nie wymaga.

Zwykle systemy maja rozne okna czasowe ktore pozwalaja refresh tokenowi odnowic access tokena. Jezeli stary access token zostal zinvalidowany np. rok temu, to refresh token - mimo ze wazny, powinien zostac
  • Odpowiedz
  • 1
@rockip: @Pasterz30 Dzięki, zagłębię się bardziej w temat. Ma to jak najbardziej sens. Nie rozpatrzyłem opcji, że refresh token jest rzadziej używany, więc w tym przypadku jego expire date nie jest aż tak istotny. No i w sumie też powinno się uwzględniać to, jak bardzo krytyczny jest to system, a nie oszukujmy się, wykop do takich nie należy
  • Odpowiedz
No i w sumie też powinno się uwzględniać to, jak bardzo krytyczny jest to system, a nie oszukujmy się, wykop do takich nie należy


@inyourbrain: Myślę nawet że głównie to. Jako że tutaj użyli uwierzytelniania tokenami tylko dlatego, że jest to teraz modne i stosowane przy SPA to też nic nadzwyczajnego by się nie wydarzyło gdyby tokeny były ważne i np. tydzień. Tak jak pewnie kiedyś była ważna sesja PHP (która
  • Odpowiedz