Łukasz Pilorz
msgbartop
Bezpieczeństwo aplikacji PHP
msgbarbottom

14 Dec 06 Dodatkowa weryfikacja sesji w PHP

Podstawowy mechanizm weryfikacji sesji w PHP sprawdza jedynie identyfikator zawarty w ciasteczku lub parametrze URL. Trzy często spotykane rozszerzenia tego zabezpieczenia to zapisywanie w sesji adresu IP lub nagłówka User-Agent, oraz weryfikacja nagłówka Referer.

Adres IP oraz nagłówek X-Forwarded-For

Dostępne w PHP jako $_SERVER['REMOTE_ADDR'] oraz $_SERVER['HTTP_X_FORWARDED_FOR'].

Oba te parametry są często zapisywane w dzienniku zdarzeń aplikacji, natomiast ich zastosowanie jako dodatkowego czynnika weryfikacji sesji jest bardzo ograniczone. Przy rosnącej popularności sieci WiFi, hotspotów i urządzeń mobilnych przypisywanie stałego adresu IP do sesji może wiązać się z utratą sporej grupy użytkowników. Korzyść z takiego zabezpieczenia jest zresztą niewielka - chroni co prawda w dużym stopniu przed wykorzystaniem ukradzionego ciasteczka z identyfikatorem sesji, ale nie zapobiega bardziej zaawansowanym atakom XSS, a w ogóle nie wpływa na bezpieczeństwo w przypadku CSRF.

Powiązanie sesji z adresem IP może być korzystne np. w przypadku niektórych aplikacji intranetowych, stosujących protokół HTTPS wyłącznie podczas logowania. Jeżeli adresy IP są przypisane do poszczególnych urządzeń na stałe, wówczas takie rozwiązanie utrudnia wykorzystanie przez atakującego podsłuchanego (nieszyfrowanego) identyfikatora sesji.

Nagłówek X-Forwarded-For pojawia się w żądaniach HTTP otrzymanych poprzez serwer proxy, i zawiera adres oryginalnego nadawcy (lub listę oddzielonych przecinkami adresów kolejnych nadawców, jeśli transmisja odbyła się za pośrednictwem kilku serwerów proxy). Tak jak większość nagłówków HTTP, może on być z łatwością sfałszowany. Błędem jest zapisywanie go w dzienniku zdarzeń zamiast adresu IP użytkownika - oba te parametry powinny być zapisywane niezależnie i osobno. Z podobnych powodów, jak w przypadku bazowego adresu IP, nie jest dobrym rozwiązaniem powiązanie go na stałe z sesją. Zamiast tego może być weryfikowany prawidłowy format nagłówka, a w przypadku negatywnego wyniku można odmówić autoryzacji bieżącego żądania.

Dość popularne jest wykorzystanie informacji o adresie IP do blokowania dostępu do aplikacji pewnym użytkownikom, lub udzielenie go wyłącznie określonej grupie adresów. W takim przypadku należy wykorzystywać wyłącznie informację o bazowym adresie IP ($_SERVER['REMOTE_ADDR']). Oparcie kontroli dostępu na nagłówku X-Forwarded-For prowadzi najczęściej do powstania luk w bezpieczeństwie aplikacji. Zwolennicy weryfikacji tego nagłówka mówią o możliwości wykorzystania przez atakującego serwera proxy do ominięcia na przykład blokady nałożonej na jego adres IP. Taka możliwość faktycznie istnieje, ale jest ona znacznie mniej niebezpieczna niż pokładanie zaufania w nagłówku, który może być podrobiony w praktycznie dowolny sposób (chociażby przy pomocy rozszerzenia Modify Headers w przeglądarce Firefox).

Nagłówek Referer

Dostępny w PHP jako $_SERVER['HTTP_REFERER'].

Parametr ten określa adres strony, z której nastąpiło odwołanie do aktualnie żądanego zasobu. Jest przesyłany przez przeglądarkę przy przechodzeniu pomiędzy stronami poprzez odnośniki, a także np. przy pobieraniu obrazków i otwieraniu strony umieszczonej w ramce. Nie musi on być wysyłany przez przeglądarkę, ponadto może być usuwany lub zmieniany przez oprogramowanie typu firewall. Nie jest zalecane wymaganie zgodności nazwy domeny w nagłówku Referer jako element identyfikacji sesji, ale jego weryfikacja może być przydatna przy sprawdzaniu poprawności danych otrzymywanych z formularzy. Obcy adres w nagłówku Referer może (nie musi) oznaczać próbę dokonania ataku CSRF.

Listę popularnego oprogramowania blokującego nagłówki Referer można znaleźć na przykład na stronach wordpress.org: http://codex.wordpress.org/Enable_Sending_Referrers (poprawne słowo to - jak w powyższym linku - referrer, ale w protokole HTTP przyjęła się błędna pisownia referer).

Nagłówek User-Agent

Dostępny w PHP jako $_SERVER['HTTP_USER_AGENT'].

W przeciwieństwie do parametrów opisanych powyżej, nagłówek User-Agent (identyfikujący oprogramowanie klienckie, np. przeglądarkę) nie powinien zmieniać się w trakcie trwania sesji. Wprawdzie może on być zablokowany lub zmodyfikowany, ale jest to zazwyczaj zmiana trwała, niezmienna w czasie życia identyfikatora sesyjnego. Jednak powiązanie tego nagłówka z sesją nie poprawia w żaden sposób bezpieczeństwa serwisu. W każdej sytuacji, w której może dojść do kradzieży identyfikatora sesji, atakujący może również poznać zawartość pola User-Agent.

Alternatywy

Zamiast wprowadzać dodatkowe parametry weryfikacji sesji, najczęściej warto pozostawić mechanizm autoryzacji wyłącznie ciasteczkom. Czas i środki lepiej jest przeznaczyć na rozbudowanie dzienników zdarzeń, wprowadzenie protokołu HTTPS, a także zabezpieczeń przeciwko atakom XSS i CSRF: filtrów danych przychodzących i wychodzących, losowych parametrów URL i formularzy, testów CAPTCHA.



Leave a Comment