W drugim wyzwaniu na bootcamp została wykorzystana serializacja danych do przechowywania stanu sesji (patrz pierwsza część wyjaśnienia do zadania). Przykłady, które prezentuje mają przedstawiać typowe problemy z bezpieczeństwem aplikacji internetowych, a nie z konkretnym środowiskiem/językiem programowania, ten przykład jest praktyczną demonstracją problemu określanego jako CWE-642: External Control of Critical State Data, o czym już kilka razy wspominałem. Warto jednak zatrzymać się na chwilę przy funkcjach serialize/unserialize w PHP.
Unserialize może zrobić krzywdę
W przypadku serializacji obiektów wywoływane są dwie ich metody:
- __sleep przy wywołaniu funkcji serialize,
- __wakeup przy wywołaniu funkcji unserialize,
W sprzyjających warunkach pozwala to na wykonanie własnego kodu na serwerze. Przykłady takich przypadków można znaleźć we wspominanej już przeze mnie prezentacji Shocking News in PHP Exploitation, taki jest też mechanizm podatności Piwik Cookie unserialize() Vulnerability.
A jak sobie z tym problemem radzić? Trzeba wykorzystać mechanizm, który pozwoli na wykrycie próby tamperingu. Oczywiście nie może to być po prostu funkcja hashująca (jeśli jej wynik jest również przechowywany po stronie klienta). W przykładach z PHP często wykorzystywana jest konstrukcja typu md5($tajnehaslo.$dane), ja jestem zwolennikiem wykorzystania hmac. Niby efekt podobny, ale lepsza forma :)