Wątek zablokowany 2012-10-11 21:17 przez Demonical Monk.

Session Hijacking, Session Fixation, XSS

0

Witam wszystkich,
chciałbym poruszyć temat zabezpieczeń stron internetowych. Poza takim atakiem jak SQL Injection, który jest łatwy do "odparcia" są dwa typy bardzo groźnych ataków, które wymieniłem w temacie. Chciałbym napisać co wiem na ich temat oraz zadać kilka pytań. Mam nadzieję że ten post pomoże też innym osobom zrozumieć to zagadnienie. Od razu polecę artykuł na którym wzoruję swoją wypowiedź: http://php.pl/Wortal/Artykuly/Bezpieczenstwo/Sesja-uzytkownika-w-PHP-zagrozenia-i-ochrona

Działam na WebServ 2.0.

Zacznę od Session Hijacking. Jest to próba otrzymania numeru ID sesji.
W ogólnie dostępnych artykułach piszą o tym by nie przekazywać numeru sesji (PHPSESSID) w URL'ach co jest akurat oczywiste, tylko w ciastkach. Mimo to wystarczy komuś podsunąć link z kawałkiem kodu JavaScript zapisującego ciastko (document.cookie) do jakiegoś pliku na naszym serwerze.

  1. W takim razie jaka jest metoda obrony ? Czyżby tylko regeneracja session_id ?
  2. Jeżeli ktoś ma wyłączoną obsługę ciastek to oznacza że automatycznie link będzie zapisany do URL ?
  3. Jak poprawnie ustawić session.cookie_path ?
  4. Czy taki kod zabezpiecza użytkownika mimo kradzieży jego sesji ?:
<?
session_start();
 
        if (!isset($_SESSION['RESET']))
        {
                session_regenerate_id(true);        // nie wiem czy lepiej usuwać poprzednią sesję, czy nie ?
                $_SESSION['RESET'] = true;         // tutaj widziałem zastosowanie z haszowaniem md5()
                $_SESSION['IP'] = $_SERVER['REMOTE_ADDR'];
        }
 
        if($_SESSION['IP'] !== $_SERVER['REMOTE_ADDR'])
        {
                // nowa sesja
        }
?>

W podanym przeze mnie artykule omawiana jest kwestia sposobu przechwytywania sesji bo jest ona zapisana do katalogu /tmp, twierdząc że standardowo CHMOD jest ustawiony na 777.
5. Ja mam 711, więc chyba po kłopocie ?
6. Omawiane są tam jeszcze kwestie długości identyfikatora, ale on jest automatycznie tworzony, czy się mylę ?

Cross Site Scripting (XSS)
Na serwerze jakim działam mimo wersji PHP 5.2.5, nie mam opcji w php.ini tj. session.cookie_httpOnly. W dodatku napisali, że działa tylko do jednej z dwóch wymienionych metod.
7. Czy ona jest na pewno ważna ?
8. Czy tak naprawdę jest jakaś skuteczna obrona przed tym ? Czy tylko nie wchodzenie w różne głupie linki ?

Session Fixation
9. W artykule został umieszczony taki kod, który jest chyba lepszym odpowiednikiem z pytania 4 ?:

session_start();
$now = time();
$regenerateSec = 1800; 
$regenerateReq = 10; 

if (!isset($_SESSION['started']))
{
    $_SESSION['started'] = true;
    $_SESSION['time'] = $now;
    $_SESSION['req'] = 1;

} else {
    $_SESSION['req']++;

    // regeneracja sesji po określonym czasie
    if (isset($_SESSION['time']) && ((int)$_SESSION['time'] + $regenerateSec < $now))
    {
        session_regenerate_id(true);
        $_SESSION['time'] = $now;
    }

    // regeneracja sesji po określonej liczbie żądań
    if (isset($_SESSION['req']) && ((int)$_SESSION['req'] > $regenerateReq))
    {
        session_regenerate_id(true);
        $_SESSION['req'] = 1;
    }
}

Wypunktowałem pytania do łatwiejszego odpowiadania (by nie było nieporozumień). Bardzo proszę o odpowiedź i wszelkie podpowiedzi związane z zabezpieczeniami. Chce się dowiedzieć czy jest możliwość zabezpieczenia się przed wszystkimi atakami, a jeżeli nie to wszystkimi możliwymi atakami na serwis poza atakami na "głupich" użytkowników, którzy wtedy sami sobie robią kuku.

Pozdrawiam i czekam na odpowiedź.

0

Przed kradzieżą ciastka może częściowo obronić ustawienie flagi httpOnly, ale pamiętaj że i tak można będzie z poziomu JS wykonywać AJAXem jakieś żądania HTTP (właściwe ciastka przeglądarka dołączy do requestu sama) lub podsunąć userowi fejkowy komunikat zbudowany via ten JS. Przypisanie ciastka do IP będzie kłopotliwe dla userów mobilnych (miliard razy zmieniające się IP w czasie dynamicznej podróży). W obliczu możliwości wymienionych wyżej niewiele zmienia.

Server-sideowa kradzież sesji tyczy się badziewnie skonfigurowanych shared hostów, których nie polecam nigdy jeżeli faktycznie chcesz mieć bezpiecznie bo tam co raz coś jest spieprzone i nawet nie masz na to wpływu.

Fiksacja sesji to bzdura, zwykle jak już masz okazję do zdobycia id sesji to i masz spore pole manewru, taką regenerację po X requestach idzie obejść floodując serwer po zdobyciu ID, wtedy sesja przechodzi na rzecz atakującego, a user tylko sam straci niespodziewanie dostęp. Najlepiej zapobiegać i sanityzować HTML i SQL jak tylko się da, a proste to to nie jest. W ramach lokowania produktu polecam "The Tangled Web" Michała Zalewskiego, genialnie opisuje przeszłość, teraźniejszość i przyszłość w temacie.

0

W artykule jest właśnie napisane, że httpOnly np: stare przeglądarki nie obsługują, więc cwańszy cracker i tak to wykorzysta. Mimo to pozwolę sobie odpowiedzieć na pytania zgodnie z tym co zrozumiałem:

  1. Jeżeli ktoś ma wyłączoną obsługę ciastek to oznacza że automatycznie link będzie zapisany do URL ?

Tak

  1. Jak poprawnie ustawić session.cookie_path ?

???

  1. Ja mam 711, więc chyba po kłopocie ?

Tak

  1. Omawiane są tam jeszcze kwestie długości identyfikatora, ale on jest automatycznie tworzony, czy się mylę ?

???

  1. Czy ona jest na pewno ważna ?

Nie jest konieczne stosowanie tego, ponieważ niektóre przeglądarki nie obsługują session.cookie_httpOnly, w dodatku nie chroni całkowicie.

  1. Czy tak naprawdę jest jakaś skuteczna obrona przed tym ? Czy tylko nie wchodzenie w różne głupie linki ?

Porządne zabezpieczanie danych wejściowych.

  1. W takim razie jaka jest metoda obrony ? Czyżby tylko regeneracja session_id ?
  2. Czy taki kod zabezpiecza użytkownika mimo kradzieży jego sesji ?
  3. W artykule został umieszczony taki kod, który jest chyba lepszym odpowiednikiem z pytania 4 ?

Te pytania wziąłem razem, ponieważ rozumiem że stosowanie kodu z pkt. 9 nie jest poprawnym zabezpieczeniem. Natomiast teoretycznie kod z pkt. 4 jest obciążeniem dla serwera (ponieważ generuje nowy numer sesji za każdym razem).
W takim razie stosować kod z pkt. 4 ?

A jak wygląda sytuacja z używaniem PHPSESSID ? Czy podczas pisania stron trzeba np: na stronach z ograniczonym dostępem sprawdzać poprawność sesji, czy robi to serwer ?

0

Ad 2 nie zaloguje się
Ad 5 to zależy
Ad 7 przeglądarki to obsługują, zawsze patrz tabelę kompatybilności.

0

Nie rozumiem odpowiedzi na ad 2.
A możesz mi odpowiedzieć na to ?

Te pytania wziąłem razem, ponieważ rozumiem że stosowanie kodu z pkt. 9 nie jest poprawnym zabezpieczeniem. Natomiast teoretycznie kod z pkt. 4 jest obciążeniem dla serwera (ponieważ generuje nowy numer sesji za każdym razem).
W takim razie stosować kod z pkt. 4 ?

A jak wygląda sytuacja z używaniem PHPSESSID ? Czy podczas pisania stron trzeba np: na stronach z ograniczonym dostępem sprawdzać poprawność sesji, czy robi to serwer ?

Niedługo kupię sobie tę książkę, o której pisałeś.

0

Tam w pytaniu drugim ma być zamiast słowa link to sesja.

0

Ad. 2: Użytkownik mający wyłączone ciasteczka się wcale nie zaloguje, serwer będzie mu nadawał nową sesję za każdym odświeżeniem strony, ponieważ przeglądarka użytkownika zignoruje nadane ciastko z numerem sesji. Tylko po co rozpatrywać takie pierdoły? Znasz kogoś nie-technicznego kto obecnie ma wyłączone ciasteczka?
Ad. 5: To zależy od konfiguracji serwera, jak mówiłem shared hostingu nie polecam.

A jak wygląda sytuacja z używaniem PHPSESSID ? Czy podczas pisania stron trzeba np: na stronach z ograniczonym dostępem sprawdzać poprawność sesji, czy robi to serwer ?

Jak rozumiesz sprawdzanie poprawności sesji? Serwer po prostu dopasowuje dane sesji do ich ID przedstawionego przez użytkownika lub generuje nową sesję jeśli użytkownik żadnej nie precyzuje/precyzowana przez użytkownika jest nieprawidłowa.

Kody zamieszczone w artykule są bez sensu, pisałem: Durne zabezpieczenia typu regenerowanie ID sesji pozwalają najwyżej atakującemu przejąć absolutną kontrolę nad daną sesją, a nie zwiększają w znaczący sposób bezpieczeństwa samej sesji. Fiksacja sesji pod kątem IP też jest moim zdaniem daremna, żądania wykonanego via AJAX nie da się odróżnić w żaden sposób od normalnego żądania, więc prosty XSS może po cichu bez żadnej wiedzy użytkownika wykonać w jego imieniu (i z jego przeglądarki!) jakieś akcje lub wyświetlić spreparowany formularz kradnący dane. Żadne sensowne zabezpieczenia nadbudowane nad mechanizmem sesji

Ad. 6: Standardowy identyfikator jest dość długi, ale możesz kontrolować sposób jego generowania poprzez session_id() polecam jednak robić to z głową i nie ruszać jeśli dokładnie nie znasz tego mechanizmu, a miewasz wątpliwości.

W artykule jest właśnie napisane, że httpOnly np: stare przeglądarki nie obsługują, więc cwańszy cracker i tak to wykorzysta.

Cytuję:

HttpOnly cookies were first implemented in 2002 by Microsoft Internet Explorer developers for Internet Explorer 6 SP1.

Zabezpieczenie pierwszy raz weszło w 2002 roku, po jakimś czasie zostało zaimplementowane we wszystkich przeglądarkach na rynku. Jeśli ktoś używa przeglądarki starszej o kilkadziesiąt lat to należy mu najwyżej współczuć, ale potencjalne podatności wynikające z używania archaicznej przeglądarki to de facto nie Twoja wina.

Mam wrażenie że artykuł pisał jakiś dinozaur, w każdym razie niewiele on ma wspólnego z faktycznym security. Przykłady kodów "zabezpieczających" przed kradzieżą sesji tylko ułatwiają sprawę dla zręcznego włamywacza i pozwalają zrobić znacznie większe zamieszanie, a same przed niczym specjalnym nie chronią.

0

Podsumowując:

  • nie pisać żadnego kodu regenerującego id sesji bo to i tak nic nie da
  • znaleźć dobry serwer
  • poustawiać odpowiednio php.ini
  • robić jak najlepsze filtrowanie danych na wejściu
  • uprzedzać użytkowników by nie dali się zrobić na "klikanie w linki"

Czy coś jeszcze ?

0

Osobiście uważam, że żadna z metod w pełni nigdy nas nie uchroni ( nawet w ssl jakiś czas temu znaleziono lukę), ale jeśli się zastosuje do tych wytycznych to na pewno nasze skrypty będą w miarę bezpiecznie. Podstawowe zasady bezpieczeństwa ładnie opisuje na swoim blogu Michał Ławicki : http://www.beldzio.com/podstawowe-zasady-bezpieczenstwa

Najważniejsze zasady stricte programistyczne, do których powinien się zastosować każdy poważnie podchodzący do sprawy bezpieczeństwa programista:

  1. Zapomnieć o wbudowanym mechanizmie sesji i tym całym session_regenerate_id(), czyli innymi słowy stworzenie klasy session handler (problemy sesji wbudowanej w php to min. Session fixation,Session poisoning,Session injection,Session riding,Session hijacking)
  2. Bezpiecznie skonfigurować PHP (php.ini) (allow_url_fopen,allow_url_include,register_globals,open_basedir,safe_mode,display_errors,expose_php,magic_quotes,session.cookie_httponly,session.use_trans_sid)
  3. Stosować funkcje filter_input ( o wiele lepsze od ctype_*, preg_mach, strip_tags etc.)
  4. Wyłączyć auto uzupełniania formularza oraz cache strony (dodatkowo jeśli jest możliwość to zalecane jest określanie dostępu dla danego adresu IP oraz szyfrowanie ssl)
  5. Stosować PDO , który ma dość dobrze rozwinięty system filtrów przyjmowanych metadanych
  6. Unikać przekazywania danych poprzez zmienna globalną GET (jeśli już zachodzi taka konieczność to każdą wartość należny odpowiednio **przefiltrować **!!!, nawet jeśli to ma być zwykła liczba, bo nigdy nie jest wiadomo co wpisze tam użytkownik, dodatkowo dla wartości numerycznych najlepiej zastosować konwersje do int)
2
com napisał(a):

Osobiście uważam, że żadna z metod w pełni nigdy nas nie uchroni ( nawet w ssl jakiś czas temu znaleziono lukę)

Zadaniem SSL nigdy nie było i nie będzie chronienie przed tego typu atakami. Średnio Ci pomoże szyfrowanie transmisji między serwerem, a klientem jeśli to serwer oficjalnie przyjmuje trefne dane wejściowe i ich nie filtruje, a o tego typu zagrywkach tutaj mówimy...

com napisał(a):

Zapomnieć o wbudowanym mechanizmie sesji i tym całym session_regenerate_id(), czyli innymi słowy stworzenie klasy session handler (problemy sesji wbudowanej w php to min. Session fixation,Session poisoning,Session injection,Session riding,Session hijacking)

W jaki sposób zmiana domyślnego mechanizmu sesji wpłynie na problemy dotyczące możliwości jej ukradzenia? :| Nawet gdybyś miał nie wiem jaki mechanizm sesji wzięty z kosmosu to i tak jeden niewinny XSS może podłożyć praktycznie idealną imitację formularza wprowadzającego użytkownika w błąd. Choćby przyciemnić okno strony i poprosić o ponowne zalogowanie się w małym formularzu "ze względów na Twoje bezpieczeństwo, bo wykryliśmy blablabla", a tak naprawdę posłać dane logowania na serwer włamywacza i spokojnie umożliwić niczego nieświadomemu użytkownikowi normalne poruszanie się po stronie. Inna sprawa, że do wykonywania akcji w imieniu użytkownika (jak np. szybka zmiana hasła po tym jak już user wypełni nasz podrobiony formularz) wcale nie potrzebujesz wykradać żadnych danych z ciasteczek. Po takiej akcji user jest totalnie udupiony i niczego nieświadomy, nic nie pomogą Twoje znachorskie sztuczki.

com napisał(a):

Unikać przekazywania danych poprzez zmienna globalną GET (jeśli już zachodzi taka konieczność to każdą wartość należny odpowiednio **przefiltrować **!!!, nawet jeśli to ma być zwykła liczba, bo nigdy nie jest wiadomo co wpisze tam użytkownik, dodatkowo dla wartości numerycznych najlepiej zastosować konwersje do int)

Co za durnoty opowiadasz, a w POST to już nie trzeba filtrować? Różnica jest minimalna, hakier może zarejestrować bardzo podobnie brzmiącą domenę i podłożyć na niej skrypt JS, który szybciutko wypełnia ukryty formularz i wysyła go do właściwej strony. Jeszcze zabawniej jak źródłowa domena jest całkiem niewinna, a tu nagle przekierowuje nas a stronę, gdzie jesteśmy zalogowani i wykonuje od razu złośliwy kod...

com napisał(a):

Stosować funkcje filter_input ( o wiele lepsze od ctype_*, preg_mach, strip_tags etc.)

Sprowadza się do tego samego co wołanie preg_match lub strip_tags, ta metoda to po prostu opakowuje. Trzeba jej używać z głową tak samo jak innych rzeczy związanych z encjonowaniem.

com napisał(a):

Wyłączyć auto uzupełniania formularza oraz cache strony (dodatkowo jeśli jest możliwość to zalecane jest określanie dostępu dla danego adresu IP oraz szyfrowanie ssl)

Co ma do tego automatyczne uzupełnianie formularza? Do reszty oszalałeś? To ułatwienie działające po stronie klienta, w dodatku rejestrujące tylko to, co faktycznie użytkownik wpisał w formularz i wyklikał. Nawet nie ma formalnej metody by to zrobić. Wyłączyć cache strony? Zajedziesz sobie serwer jeszcze bardziej i nic to nie zmieni. O bezpieczeństwie wiesz tyle, co typowy klepacz PHP.

1

@com: bardzo dobrze stosujesz sie do tego co napisales, piec plus: http://escucu.byethost33.com/
ostatnio jakis sztorm gimbusow na 4programmers, idzcie wy sie dodawania uczyc i czytac swoja lamerska szkole hakerow

0

Dziękuję za odpowiedzi.
Co to za strona ? http://escucu.byethost33.com/

Czyli podsumowując: trzeba zabezpieczyć stronę przed atakami nie na nią, a na "głupich" użytkowników?

0
Zi00mal napisał(a):

Dziękuję za odpowiedzi.
Co to za strona ? http://escucu.byethost33.com/

strona pochodzi z portfolio tego madrali @com, wlasnie widac jak sie sprawdzaja w praktyce te [CIACH!] ktore napisal

Michal.Zawadzki napisał(a):

Czyli podsumowując: trzeba zabezpieczyć stronę przed atakami nie na nią, a na "głupich" użytkowników?

robic swoje, filtrowac input niezaleznie skad pochodzi, znac podstawy mechanizmow z ktorymi mamy stycznosc na codzien (to bardzo wazne) i nie wdawac sie w jakies durne zabezpieczenia jesli nie jestesmy pewni ze nic nie spieprzymy

1 użytkowników online, w tym zalogowanych: 0, gości: 1