Witaj, Gościu O nas | Kontakt | Mapa
Wortal Forum PHPEdia.pl Planeta Kubek IRC Przetestuj się!

Sesja użytkownika w PHP - zagrożenia i ochrona

Session Hijacking

Session Hijacking odnosi się do tych wszystkich ataków, gdzie kraker próbuje uzyskać dostęp do istniejącej sesji użytkownika, tj. gdy identyfikator został przydzielony już wcześniej.

Przeciwdziałanie przechwyceniu identyfikatora sesji

Sposób przekazywania identyfikatora sesji

Identyfikator sesji możemy przekazywać zarówno w adresie URL, jak i w ciasteczku. Pierwszy z wymienionych sposobów zdecydowanie nie jest dobrym pomysłem, ponieważ:

  • Każda osoba używająca tego samego komputera będzie mogła poznać identyfikator sesji z historii stron przeglądarki.
  • Adresy URL często zapisywane są przez serwery proxy, dzienniki zdarzeń, itp. W wyniku ich analizy można przeczytać identyfikatory sesji.
  • Bardzo łatwo zmodyfikować identyfikator sesji poprzez manipulacje łańcuchem żądania.
  • Kiedy użytkownik przechodzi na inną stronę, adres URL wraz z identyfikatorem sesji dostępny jest w nagłówku HTTP Referer.
  • Użytkownik, przekazując adres URL innym osobom, nieumyślnie udostępnia także identyfikator sesji.

Naturalnym wyborem do przekazywania identyfikatora sesji są więc ciasteczka. Wadą tego rozwiązania jest to, że odwiedzający stronę ma pełne prawo i możliwości do odmówienia przyjęcia cookie. Niestety coś za coś. Lepszym wyjściem jest jednakże wyjaśnienie użytkownikowi dlaczego ciasteczka są potrzebne, niż opieranie obsługi sesji na rozwiązaniu, które nie jest bezpieczne.

Aby wymusić używanie ciasteczek do przekazywania identyfikatora sesji powinniśmy ustawić odpowiednie dyrektywy konfiguracyjne :

  • session.use_cookies - ustawia przekazywanie identyfikatora w ciasteczkach,
  • session.use_only_cookies - ustawia pobieranie identyfkatora tylko z ciasteczek,
  • session.trans_sid - ustawia przekazywanie identyfikatora poprzez adres URL i formularze WWW? możliwość tą oczywiście należy wyłączyć.

W konfiguracji powinniśmy też ustawić odpowiednie parametry dotyczące samego ciasteczka sesji ( session.cookie_lifetime, session.cookie_path, session.cookie_domain, session.cookie_secure, session.cookie_httponly). Szczególną uwagę należy zwrócić na ograniczenie ścieżki, dla której powinno ono obowiązywać, ponieważ domyślne ustawienie dla całego głównego katalogu "/" zwiększa pole do manewru dla atakującego.

Ochrona przed Cross Site Scripting (XSS)

Cross Site Scripting polega on na wstrzykiwaniu złośliwego kodu w oryginalną treść strony przeważnie poprzez wszelkiego rodzaju formularze internetowe, gdzie zatwierdzona treść jest potem wyświetlana. XSS może być także wykorzystany do wykradnięcia ciasteczka zawierającego identyfikator sesji :

<script>alert(document.cookie());</script>

Jak się zabezpieczyć? Z pomocą przychodzi tutaj flaga cookie httpOnly. Jej zadaniem jest instruowanie przeglądarki, aby nie udzielała dostępu do obiektu document.cookie jakimkolwiek językom skryptowym działającym po stronie klienta, np. JavaScriptowi. Począwszy od PHP 5.2.0, aby ją włączyć domyślnie dla wszystkich ciasteczek sesyjnych wysyłanych przez aplikację, wystarczy ustawić dyrektywę session.cookie_httponly. Rozwiązane to nie jest jednak pozbawione wad. Po pierwsze należy mieć świadomość, że nie wszystkie przeglądarki wspierają httpOnly - dotyczy to zwłaszcza starszych wersji. Po drugie cookie wciąż może być odczytane używając metody TRACE (tzw. Cross Site Tracing).

O ile w pierwszym przypadku jedyne co nam pozostaje to namawianie użytkowników do aktualizacji używanych przeglądarek, o tyle w drugim możemy się zabezpieczyć uniemożliwiając wykonanie metody TRACE na poziomie serwera np.

Pamiętajmy jednak, że w przypadku ataków typu XSS, przede wszystkim powinniśmy zawsze dogłębnie filtrować wszystkie dane wejściowe, tak aby niemożliwe było wstrzyknięcie i wykonanie obcych skryptów.

Sposób przechowywania danych sesyjnych

Rozszerzenie PHP Session domyślnie przechowuje dane sesyjne w plikach na serwerze lokalnym w jednym katalogu (/tmp). Na serwerach współdzielonych, prawa odczytu i zapisu do tego katalogu mają wszyscy użytkownicy i w praktyce mogą uzyskać dostęp do wszystkich identyfikatorów oraz danych sesji. Co więcej, atakujący może to wykorzystać do podmiany pliku sesji lub danych w nim zawartych.

Aby zabezpieczyć się przed tym zagrożeniem, najlepiej skorzystać z dyrektywy konfiguracyjnej session.save_path, która wskazuje nowy katalog do przechowywania plików sesji.

ini_set('session.save_path', '/bezpieczna/lokalizacja/sesji');

Inny sposób to zdefiniowanie własnych funkcji do obsługi magazynu przechowywania danych sesyjnych, np. do zapisu w bazie danych lub pamięci współdzielonej (ze względów wydajnościowych pierwsza opcja zdecydowanie nie jest dobrym pomysłem). Funkcje te rejestrujemy za pomocą session_set_save_handler().

Dodatkowo, w systemach, w których wymagany jest wysoki poziom bezpieczeństwa, dane sesyjne możemy zabezpieczyć poprzez szyfrowanie bezpośrednio przed umieszczeniem w magazynie danych, chociażby używając rozszerzenia Mcrypt. Nie zaszkodzi także użycie sumy kontrolnej dla sprawdzenia integralności danych. Wtedy, nawet gdy ktoś dobierze się do plików przechowujących dane, to i tak nie będzie mógł ich ani odczytać, ani zmienić.

Zapewnienie odpowiedniej siły identyfikatora

Identyfikator sesji powinien być odpowiednio długi i losowy, trudny do odgadnięcia oraz trudny do odtworzenia. Wbudowany mechanizm obsługi sesji prezentuje się pod tym względem dość dobrze - do wyboru daje funkcje skrótu MD5 i SHA-1 o różnej długości - dyrektywy session.hash_function oraz session.hash_bits_per_character. Dodatkowo możemy spowodować zmianę w działaniu generatora liczb losowych poprzez użycie dyrektyw session.entropy_file oraz session.entropy_length. Wskazują one plik i długość ciągu w tym pliku, który ma być użyty do wygenerowania identyfikatora, np. może to być /dev/random, który w systemach Linux zwraca losowe wartości. Jednakże dla początkujących programistów lub po prostu niezbyt pewnie się czujących w temacie, radziłbym co najwyżej zmianę algorytmu na SHA-1, w przeciwnym razie wszelkie zmiany konfiguracji mogą mieć całkiem odwrotny efekt.

Podsłuchiwanie ruchu sieciowego

W ruchu sieciowym standardowo wszystkie dane wysyłane są tekstem jawnym. Każdy, komu uda się podsłuchać ruch, z łatwością może przechwycić i wykorzystać identyfikator sesji. Jedynym rozwiązaniem jest wykorzystanie bezpiecznego protokołu HTTPS. Wtedy komunikacja pomiędzy klientem i serwerem jest w pełni szyfrowana. Wdrożenie SSL nie zawsze jest jednak możliwe, zwłaszcza w przypadku niskobudżetowych przedsięwzięć. Na szczęście stosując inne techniki opisane w tym artykule możemy zapewnić wystarczająco wysoki poziom bezpieczeństwa.

Przeciwdziałanie skutkom przejęcia identyfikatora

Kontrola czasu trwania sesji

Sesje, które nie wygasają w odpowiednio krótkim odstępie czasu, dają atakującemu o wiele więcej możliwości na atak. Mechanizm obsługi sesji musi w pełni kontrolować czas, po jakim sesja traci ważność albo jest usuwana z magazynu przechowującego. Sesja powinna być przerwana, gdy nie stwierdzono żadnej aktywności przez pewien okres czasu, np. 30 minut, lub gdy nastąpi błąd bezpieczeństwa. Użytkownik powinien mieć także możliwość przerwania sesji samemu, poprzez opcje wylogowania z systemu. Mechanizm powinien automatycznie usuwać z magazynu danych te identyfikatory i dane sesyjne, których czas ważności został przekroczony. Także ciasteczka powinny mieć ograniczony czas istnienia.

<?php
session_start();$now = time();// czas trwania sesji w sekundach
$expiryTime = 1800;// nowa sesja - ustaw czas początkowy sesji
if (!isset($_SESSION['last_trace']))
{
    $_SESSION['last_trace'] = $now;
}// sesja wygasła
elseif ((int)$_SESSION['last_trace'] + $expiryTime < $now)
{
    $sessionName = session_name();    $_SESSION = array();
    if (isset($_COOKIE[$sessionName]))
    {
        setcookie($sessionName, '', $now-3600, '/');
    }
    session_destroy();    echo 'sesja wygasła!';
}

Podwójne uwierzytelnianie

Krytyczne operacje dla działania systemu oraz konta użytkownika, jak np. zmiana hasła, powinny być poprzedzone ponownym uwierzytelnianiem (podaniem hasła). W ten sposób mocno ograniczamy straty, jakie mogłyby wyniknąć w wyniku przejęcia sesji przez krakera.

Informacje na podobny temat:
Wasze opinie
Wszystkie opinie użytkowników: (3)
Dlaczego
Środa 10 Sierpień 2011 7:13:42 pm - chormi <niemozna_at_docholery.wydrukowac>

sobie takiego artykułu.

sesje
Wtorek 03 Luty 2009 10:49:32 am - rasp

Bardzo dobre podsumowanie tematu.

dobry artykuł
Sobota 06 Grudzień 2008 5:47:02 pm - czachor

Dobra robota. Sam byłem trochę niedouczony w temacie, więc artykuł przydał się. Dobrze i czytelnie napisany, czekam na więcej ;)

Mentax.pl    NQ.pl- serwery z dodatkiem świętego spokoju...   
O nas | Kontakt | Mapa serwisu
Copyright (c) 2003-2017 php.pl    Wszystkie prawa zastrzeżone    Powered by eZ publish Content Management System eZ publish Content Management System