21:24
19/8/2014

Jeden z naszych czytelników, Michał, poinformował nas o ciekawej sytuacji, jaka niedawno go spotkała. Otrzymał e-maila od nieznanej mu osoby, która przeglądając serwis GoldenLine przypadkiem zalogowała się na jego konto…

Pan jest na moim koncie, proszę się wylogować!

Przypadkowy internauta, Krzysztof, tłumaczy, że przeglądając serwis GoldenLine na przeglądarce mobilnej po prostu został zalogowany na czyjeś konto. Chciał sprawdzić, czy nie jest to problem z wiązany z cachem, więc postanowił zaprosić do przyjaciół swój prawdziwy profil …i w istocie otrzymał e-maila od użytkownika, na którego został przypadkowo zalogowany. Krzysztof miał więc pełną kontrolę nad czyimś kontem. Zamiast jednak z niej skorzystać w nieetyczny sposób, poinformował on prawdziwego właściciela konta — naszego czytelnika, Michała.

Oto korespondencja Michała z serwisem GoldenLine:

GoldenLine - zgłoszenie faktu zalogowania na przypadkowe konto

GoldenLine – zgłoszenie faktu zalogowania na przypadkowe konto

Sami również zwróciliśmy się do GoldenLine w tej sprawie z prośbą o komentarz. Oto odpowiedź Sebastiana Grodzickiego (CTO GoldenLine):

W przytoczonym przypadku doszło do tzw. kolizji klucza sesyjnego. Jest to sytuacja niezwykle rzadka, lecz przy ruchu, jaki obsługuje GoldenLine, była niestety możliwa. Podjęliśmy natychmiast odpowiednie kroki, aby zapobiec podobnej sytuacji w przyszłości poprzez zmianę funkcji skrótu oraz zwiększenie entropii podczas generowania klucza sesyjnego. Pragnę dodać, iż wprowadzone przez nas zmiany przewyższają kilkukrotnie zalecenia OWASP.

Kolizje się zdarzają

Z sytuacja podobną do opisanej powyżej mieliśmy do czynienia osobiście …na Facebooku. Chcąc założyć testowe konto, po odpaleniu przeglądarki w trybie incognito i wejściu na facebook.com, jednemu z naszych redaktorów ukazał się następujący widok:

Wejście na cudzą sesją na Facebooku

Wejście na cudzą sesją na Facebooku

Profil był zarejestrowany na numer telefonu:

Dane przypadkowo "przejętego" użytkownika Facebooka

Dane przypadkowo “przejętego” użytkownika Facebooka

Wykonane testy wykluczyły problem z “nieodświeżeniem” się cache lub błędną pracą load balacera w sieci lokalnej, a hipotezy jakie się pojawiły w dskusji, to:

Mam konto w serwisie internetowym, co robić, jak żyć?

A ponieważ przed powyższymi problemami pomimo najszczerszych chęci czasem ciężko jest się zabezpieczyć (chociaż można próbować “ulepszać” mechanizm sesji), wniosek jest tylko jeden:

Wszystkie wgrywane do internetu materiały (zdjęcia, pliki, e-maile) traktuj jako publicznie dostępne. Dla każdego. Do końca świata.

Co by się stało, gdyby ktoś przypadkiem wszedł na Twoje konto na Facebooku? Albo GMailu? Albo ePUAP-ie? Co tam znajdzie? Jeśli komuś brak wyobraźni w tym zakresie, ciekawym case-study są wykradzione i upublicznione rozmowy jednego z członków ONR.


Przeczytaj także:



76 komentarzy

Dodaj komentarz
  1. Ciekawe…
    Czyli, teoretycznie, odpowiednia ilość “odświeżeń strony” może doprowadzić do wejścia na losowe konto?
    Przyznam, że wyglàda to absurdalnie

    • Nie odświeżeń tylko logowań. Chodzi o to, że przy logowaniu na jakiś określony bądź nieokreślony czas nadawany jest numer sesji, który jest przechowywany w przeglądarce, a na serwerze jest przypisany do konkretnego użytkownika i jeśli przy logowaniu wygeneruje się klucz, który jest już w użyciu to pokaże się konto, do którego klucz był wcześniej przypisany

    • Z czyszczeniem ciastek, bo klucz jest tam przechowywany.

    • Stawiam piwo, że mniej więcej 90% internetu stoi na najprostszych możliwych phpowych sesjach. Ustawiają Ci cookies z jakimś numerkiem i na tej podstawie stwierdzają, że Ty to Ty. Jak ktoś sobie tego cookiesa wklei do wgeta albo swojej przeglądarki to zrobił hijack sesji.

      Oczywiście są tu finezyjne metody sprawdzania tego z adresem IP, bezkolizyjnego generowania itd. albo jakieś uwierzytelniania po WSSE, czy inne cuda, ale dla większości stron jak ktoś Ci skopiuje cookiesa i odpali w swojej przeglądarce w Pekinie to jest to całkowicie OK.

    • oskar a już myślałem że można w ten sposób zalogować się z wylogowanego przez kogoś konta, przejmując cookies. Nie znam się tak dobrze na security.

  2. Czy dwuetapowa weryfikacja w jakimkolwiek serwisie w tym przypadku pomoże w jakiś sposób zabezpieczyć konto, czy w takim przypadku zostanie ona pomięta?

    • Nie pomoże bo sesja jest nadawana wraz z zalogowaniem się do serwisu a nie przed :)

  3. No trochę słabe rozwiązanie ze zwiększeniem entropii i funkcji skrótu. Wystarczyło by podczas generowania klucza sesji dla nowego usera sprawdzać czy przez przypadek nie istnieje już taka sesja.

    • A pomyslałeś jaki jest “koszt” takiego przeszukania ? Przecież tam są miliardy sesji…

    • @Łukasz, z tymi miliardami to bez przesady.
      Nawet gdyby było ich kilkaset tysięcy, przeszukanie takiej ilości danych nie jest szczególnym wyzwaniem dla mocniejszych serwerów.
      Można też posiłkować się np sumą kontrolną – wyznaczać ją dla każdego tokena sesji przy jej zakładaniu i zapisywać gdzieś. Potem przeszukać bazę najpierw pod kątem tej sumy (otrzymamy ułamek z całości), a potem przeszukać podzbiór już pod kątem całego tokena.

    • @Lukasz tak samo jak jest miliard adresów email, a mimo to podczas logowania ci go znajduje w bazie.

    • @Filip: Ale adresy email można zindeksować.

    • Jaki koszt? Przecież i tak takie wyszukiwanie jest robione, żeby podać dane użytkownika do wyświetlenia na stronie (na podstawie sesji).

    • Jaki koszt? Prosty memcache/redis z listą kluczy sesyjnych i takie coś robisz w tysiącach/sekundę na jakimś podrzędnym serwerku :)

    • @Szymon “tysiące/sekundę” to bardzo wolno :) Nie wiem czy n użytkowników chciałoby tyle czasu czekać na zologowanie

    • @Lukasz miliardy sesji? Z całym szacunkiem, na GoldenLine? :-D

    • Wystarczy dodatkowo stare dobre (i chyba zapomniane przez wygodnictwo) zabezpieczenie – w skrócie kodem if($ip != $lastip) { logout(); die; }; $lastip=$ip;
      No ale wiem – lenistwo i wygodnictwo = włażenie w d* luzerom ;)

    • @BloodMan nie ma żadnego wymagania, abym całą sesję wykonał z jednego źródłowego IP. Co mam zrobić jeśli mam dwa łącza i naiwny load balancing na poziomie sieci (np. wybór łącza wychodzącego na podstawie src addr+src port+dst addr+dst port)? Wiele małych sieci osiedlowych etc. Rozumiem, że z Twoich websajtów nie skorzystają.

    • @Wujek Staszek: szczerze? loadbalancing jest źle zrobiony… ;)

      Ogólnie mówiąc chyba nie zaprzeczysz że to zabezpieczenie jest dobre – natomiast oboje wiemy że jest niewygodne. Tylko pytanie czy zabezpieczenia powinny się naginać przed wygodą? No to może w ogóle wywalmy loginy i hasła… przecież wygodniej jest ich nie wpisywać …

      Ale jeśli chcesz to nie musisz używać prostej wersji kodu – możesz rozszerzony pomysł w deseń:
      jeśli aktualne ip się zgadza z 5 ostatnimi które się zalogowały to OK ; else zaloguj()
      ;)

    • @BloodMan krótkie podsumowanie, dlaczego to jest zły pomysł – zmienne ip.

    • “No to może w ogóle wywalmy loginy i hasła… przecież wygodniej jest ich nie wpisywać …”

      Błagam, co to za argument. No to może w ogóle nie korzystajmy z Internetu… przecież bezpieczniej jest tak właśnie zrobić…

  4. Szatan! ;)

    • Nie wiem dlaczego, ale śmieję się zbyt mocno z tego :D

  5. tl;dr, function getRandomSessionToken() { return md5(mt_rand(0, 10000000000)); } ? :P

    • Właśnie dlatego są kolizje. Z braku szacunku dla słabości MD5 i słabych PRNG, i entropii w ogóle.

    • Wciąż mogę wylosować taką liczbę jak Ty przy dostatecznie dużej ilości powtórzeń.

    • @dragoon aethis jeśli już to mt_rand(0, PHP_INT_MAX) choć całość i tak nie ma sensu jak już ci napisali.

    • Jeśli już, to openssl_random_pseudo_bytes().

  6. Wygląda na nowy rodzaj ataku – brute refresh :-).

  7. ciekawe ile osób teraz siedzi i odświeża facebooka :D

  8. Szybkie pytanie. Czy wszystkie screeny na niebezpieczniku muszą być takie małe? Czytanie tekstu z pierwszego obrazka to nic przyjemnego, a nawet można powiedzieć, że męczy wzrok.

    • ctrl + scroll myszki

  9. Czy nie lepiej aby klucz sesji, oprócz składnika (pseudo)losowego, zawierał w sobie jakiś składnik stały, unikalny dla każdego użytkownika? Ewentualnie przekazywanie tych danych w oddzielnych parametrach. Wtedy będą musiały spasować jednocześnie: numer użytkownika i klucz pod którym otworzył sesję ten właśnie użytkownik.

    • Tak jest w fejsie ;)

  10. Podobną sytuację miał kolega w pracy, tylko że na Endomondo. Nagle zalogował się na konto jakiegoś warszawiaka. I nikt nie wiedział ocb :)

    • nabiegał mu statsy?

    • Biegał do tyłu i prawie mu wyzerował statsy!

    • usiadł na ławce i zaniżył średnią

  11. Miałem kiedyś podobną sytuację z pewnym serwisem którym administrowałem – serwis pisany w Perlu, w jednym z modułów nie było “use strict” na początku i w pewnym momencie było odwołane do zmiennej trzymającej ID sesji. Ponieważ zmienna nie była wcześniej inicjowana, a całość chodziła pod modperlem więc w efekcie przy spełnieniu paru warunków logujący się użytkownik dostawał ID sesji innego zalogowanego użytkownika. I działy się cuda.
    Prawdę mówiąc średnio wierzę w kolizję funkcji skrótu. Pierwsze pytanie – czy użytkownicy byli zalogowani w tym samym czasie?

    • Również nie wierzę w “kolizję” tego typu, tym bardziej że wystarczy odpytać goldenline i od razu widać, że nie ustawiają nagłówków w poprawny sposób.

      Z całym szacunkiem dla niebezpiecznika, z zewnątrz nie jesteście w stanie wybadać czy problem wynika z nieświeżym cache, podaniem reprezentacji z nagłówkiem Set-Cookie czy czymś innym…

    • @adrb ale oni pisza ze sprawdzali problemy za cachem na trasie od siebie do serwisu, i to mogli spokojnie zorobic. pewnie chodzi o testy roznego rodzaju proxy operatorskich. a tobie pewnie chodzi o problemy z cache’em po stronie wewnetrznej samego serwisu to rzeczywiscie ciezko jest zdiagnozowac. czasem mozna bawic sie w podmiane tokenow ladbalancerowych i testowaniu co nody zwracaja ale to nie daje pelnego obrazu.

    • Ja wierzę, bo widziałem. Kolizję GUIDów widziałem. Brzytwa Ockhama. Wyjaśnienie zazwyczaj jest tak proste, że trudno w nie uwierzyć. Komentarz @Dragoon Aethis tylko mnie upewnił, że należy szukać rozwiązań w kolizji kluczy sesji. Biorąc pod uwagę, że to PHP, jeszcze bardziej w to wierzę.

    • @iRek, tak oczywiście chodziło mi o cache reverse proxy

      @Wujek Staszek, pomyśl i poczytaj zanim coś napiszesz. Cytowany przez Ciebie wpis nic nie udowadnia. Na początek polecam:

      http://php.net/manual/en/session.configuration.php#ini.session.hash-function

      Nawet jeżeli używają md5, przy tej skali ruchu jaką ma goldenline, trafienie kolizji jest mniej prawdopodobne jak wygranie w totka.

      Bardziej prawdopodobny jest błąd (nawet chwilowy) w cache-u pośrednim. By daleko nie szukać, dla przykładu squid 3.1 posiada tego typu błąd, chociaż oni akruat uzywają varnish i nginx.

      Apropo nginx, poczytaj jak działa jego cache ;]

  12. Ktoś wie, ile mieli wcześniej losowych bitów w session id? I ile mają teraz na FB?

  13. Niech zagrają w totka :)

  14. Ciekawy błąd miał wiele lat temu serwis sympatia. Można było umieszczać swój kod na stronie-profilu. Umieściłem tam adres obrazka prowadzący do skryptu php. Przy każdym wejściu na stronę skrypt podsyłał mi referera z… session id. Wystarczyło kliknąć w takiego referera aby cudownie znaleźć się na cudzym koncie. W refererze zaszyte były też inne informacje typu wybrane ustawienia wyszukiwania. Łatwo się domyśleć jak to ułatwiało kontakt z “ofiarą”. “Szukasz faceta ….” ;)

  15. Szatan. Na sto procent Szatan.

  16. Czepię się może nieistotnego aspektu sprawy, ale dla mnie denerwującego.
    Zdanie “Chcąc założyć […] ukazał się […] widok” oznacza że to widok chciał założyć konto, a nie redaktor.
    Proszę o naprawienie błędu i przekazanie Słownika Języka Polskiego do wybranej biblioteki:>

    • +1

  17. Mnie się też to niedawno zdarzyło. Logując się do wewnętrznej, korporacyjnej strony z e-szkoleniami weszłam na czyjeś konto, także może to nie jest aż tak rzadkie zjawisko?

  18. NuPlays.pl podczas startu sprzedaży przedpremierowo płyty miało to samo często i gęsto. Ludzie zamawiali i oplacali zakup płyt na nie swoje dane.

  19. Miałem kilka lat temu podobną sytuację, posiadałem jeszcze konto pocztowe na onecie i po zalogowaniu na pocztę, pokazało mi się kompletnie nie moje konto. Były tam maile od nieznanych mi osób, zdjęcia itp, wszystko działało bezproblemowo do momentu wylogowania.

  20. Obstawiam słabą metodę generowania klucza sesji przez PHP (którego używa zarówno GoldenLine jak i Facebook), wynikiem czego są kolizje częstsze niż “ustawa przewiduje”. W przypadku dużej liczby logowań warto być paranoikiem i użyć własnego generatora klucza sesji, z dużą liczbą bitów, np. 512, opartego oczywiście na dobrym PRNG, którego dodatkowo od czasu do czasu “przyprawimy” prawdziwą entropią z /dev/random. Dodatkowy warunek – brak błędów podczas implementacji :-)

    A może po prostu wystarczyłoby wziąć 3 GUIDy i skonkatenować je, to daje do 366 bitów entropii i niezłą dawkę paranoi, też nieźle :)

    Jeśli to nie słabe klucze sesji, to na pewno Szatan.

  21. wniosek: ciastka to zło. konieczne?

    • Skoro Piotr jest Konieczny, to ciastka też ;).

      Pozdrowienia dla Redakcji. Nieźle się z szatana uśmiałem.

  22. Witam,

    Miałem podobną sytuację.
    Około rok temu logując się na swoje konto, gmail załadował mi konto zupełnie innego użytkownika. Tak jak pisaliście, pełna kontrola, przeładowanie strony nie pomagało.
    Pomogło wylogowanie i zalogowanie się ponownie.

    Pisałem o tym fakcie do googla, ale żadnej odpowiedzi nie dostałem.

    Pozdr

  23. Wniosek? Jedno ip w ramach sesji. Niektóre banki tak przecież sprawdzają.

    • W przypadku banków może i tak, ale przy normalnych stronach… W dobie internetu mobilnego, to dla mnie słaby pomysł. Jadąc do pracy np. autobusem jak będę przeglądał taką stronę, to co wtedy? Co chwila będę się musiał logować?

    • Ojej. I ciągle zmienia ci się IP ?

    • Nie zawsze trzeba aż tak drastycznie (powiązanie z IP). Tzw. Browser fingerprinting na tego typu sytuacje może sie całkiem nieźle sprawdzić.

    • Poprawny (czyli nie łapiący połowy internetu) fingerprinting jest dość skomplikowany do zrobienia. Tak trochę przestaje się ekonomicznie opłacać (robota, zasoby podczas działania, etc.) :]

      Więc jeśli już nie IP, to drugie kontrolne cookie z md5($userid). W końcu chyba 2 kolizje na raz się nie zdarzą… częściej niż raz na sto lat ;p

  24. Kiedyś podobna sytuacja zdarzyła mi się z gmail’em. Pisałem do niebezpiecznika w tej sprawie, ale moja informacja została delikatnie mówiąc olana.

  25. Jak X lat temu zaczynalem zabawe z aplikacjami webowymi to juz wtedy jako poczatkujacy robilem cos takiego:
    do {
    $session_id = generuj_sid();
    while (sid_istnieje($sess_id));

    bo nie ufalem losowosci swojej funkcji generujacej, ktora robila mniejwiecej md5(random()).
    Tak czy siak, prosty while i obojetne jak dziala generuj_sid() szans na kolizje NIE MA.

    Druga sprawa, ze session ID powinno byc sprzezone z adresem IP celem zabezpieczenia przed session hijacking.
    Komputery stacjonarne zadko zmieniaja IP – nie czesciej niz co 24h (restart routera, itp.) – wiec problemu nie ma. Rozumiem, ze w przypadku app mobilnych bylo by to uciazliwe wiec sie nie czepiam ;)

  26. A jak sprawa wygląda z bankami? Też można się zalogować na czyjeś konto?

  27. Kilka lat temu miałem taką samą sytuację. Rozmawiałem z kolegą na GG i byliśmy zalogowani na tej samej witrynie. Po jakimś czasie zostałem przelogowany na jego profil, a on na mój. Do dnia dzisiejszego nie byłem pewny o co dokładnie mogło chodzić. A to tylko kolizja klucza sesyjnego.
    PS Miałem kiedyś jeszcze dziwniejszą sytuacją. Podczas rozmowy telefonicznej w pewnym momencie usłyszałem głos nieznajomej kobiety, która była równie zdziwiona, jak ja. Jakimś cudem moja rozmowa (już trwająca) została przekierowana do innego odbiorcy.

  28. szatan. – najlepsze

  29. To pewnie przez deszcz meteorytów w tym czasie powiązany ze złą aura dla strzelców. ..

  30. Ja mysle,ze problem spowodowal jednak wspomniany Szatan. Nie dostrzegam innej mozliwej przyczyny…

  31. Losowy klucz sesji o długości 128 bitów lub więcej jest bezpieczny. Szansa na kolizję w takim przypadku jest tak mała że nie ma sensu się tym przejmować. Ale 64 bitów raczej bym nie zaryzykował.

  32. Osobiście miałem taką sytuację z kontem WizzAir. Przeglądałem loty na stornie swojej dziewczyny, po czym klik klik i jestem na koncie jakiejś laski. Pełna kontrola, możliwość sprawdzenia historii lotów, nr tel, adres zamieszkania itp. Zadzwoniłem i poinformowałem ją o tym fakcie, tak samo WizzAir – wysyłając screenshoty jako dowód. Zadzwonili do mnie z centrali, ale nie chcieli mi za bardzo uwierzyć ;/

  33. A dla czego nie mówimy tutaj o 2FA?
    To rozwiazanie powinno dac rade – prawda?

  34. Koleżanka miała to samo z fb jakieś pół roku temu. Chciała się zalogować, a otworzyło jej się konto osoby, której wogóle nie znała. Widziałem na własne oczy. Ciekawe jak często się to zdarza…

  35. zdarza się mi raz zalogowało do czyjegoś Gmaila może to celowy bug jakiś stworzony przez jakaś 3 literowa agencje p

  36. […] Jakiś czas temu opisywaliście przypadek kolizji klucza sesyjnego w serwisie GoldenLine. […]

  37. […] serwisowi GoldenLine, co powodowało logowanie się na cudze konta i dostęp do ich danych (por. Przypadkiem wszedł na konto innego użytkownika w GoldenLine)? Przyczyną błędu mogą być też problemy z serwerami cache’ującymi (co tłumaczy, […]

Twój komentarz

Zamieszczając komentarz akceptujesz regulamin dodawania komentarzy. Przez moderację nie przejdą: wycieczki osobiste, komentarze nie na temat, wulgaryzmy.

RSS dla komentarzy: