Bezpieczny safe_mode ?
Jak często mamy do czynienia na serwera współdzielonych z włączonym tak zwanym trybem bezpiecznym czyli safe_mode, jednak czy tryb ten ma coś wspólnego z bezpieczeństwem ? Jak się bowiem okazuje stwarza on bowiem zwykłe pozory bezpieczeństwa, utwierdzając mniej obeznanych administratorów w przekonaniu, iż jest on złotym środkiem na ich problemy z bezpieczeństwem skryptów PHP na ich serwerze.
Ale może od początku – czym jest właściwie safe_mode? Ogólnie mówiąc safe_mode wymusza sprawdzanie właściciela pliku który jest wykonywany oraz właściciela zasobu (pliku, folderu), na którym ma zostać wywołana akcja dopuszczając jedynie operacje gdzie zasób i skrypt należą do tego samego właściciela. W mniej restrykcyjnym podejściu sprawdzanie może polegać na porównaniu wyłącznie grupy do której należy zasób. Brzmi sensownie? – możliwe, jednak w rzeczywistości rozwiązanie to sprawia więcej problemów, i stwarza jedynie pozory bezpieczeństwa (oczywiście odpowiednia konfiguracja serwera może zmniejszyć te pozory przekładając to na rzeczywiste bezpieczeństwo), niemniej jednak czy zrekomensuje to utrudnienia jakie spowoduje? Moim zdaniem nie (i wydaje mi się, iż zdanie to jest zgodne z myślą twórców PHP, bowiem od PHP 6.0 safe_mode zostanie zlikwidowany)
Jakich problemów możemy się spodziewać przy wykorzystaniu safe_mode? Jednym z częściej spotykanych są problemy związane z uploadem plików, oraz tworzeniem folderów przy wykorzystaniu PHP. Mianowicie w trybie safe_mode nie możemy tworzyć plików w folderach utworzonych przy wykorzystaniu safe_mode – spowodowane to jest faktem, iż katalog tworzony jest w innym do którego serwer www posiada uprawnienia zapisu, jednak właścicielem tego folderu jest użytkownik który umieścił pliki na serwerze – jest to prawie zawsze inny użytkownik niż ten, z prawami którego działa serwer. W efekcie takiego działania powstaje nowy folder utworzony przez serwer www, który jest jego właścicielem – i tu pojawia się problem skrypt należy do użytkownika który go umieścił na serwerze, natomiast folder do użytkownika z prawami którego działa serwer i tutaj do działania wkracza safe_mode, który wykrywając konflikt UID odbiera nam możliwość manipulowania utworzonym przez nas folderem.
Wracając do głównego tematu – jakim jest pozorne bezpieczeństwo trybu safe_mode, co mam na myśli mówiąc pozorne bezpieczeństwo? Chodzi mianowicie o stosunkowo proste sposoby obejścia restrykcji nakładanych przez tryb safe_mode, np. przy zastosowaniu prostej funkcji copy() możemy przekopiować skrypt utworzony przez nas do nowego pliku utworzonego przez serwer, dzięki tej prostej czynności otrzymujemy skrypt, z UID właściciela serwera co daje nam nieograniczony dostęp do zasobów których jest on właścicielem. Jak więc widzimy ograniczenie to jest niezwykle proste do obejścia.
Kolejnym przykładem pokazującym słabość trybu bezpiecznego jest fakt, iż ograniczenie to tyczy się funkcji wykonywanych bezpośrednio poprzez PHP, a co za tym idzie całkowicie dozwolone jest wykonanie następującego kodu:
shell_exec(“rm –rf /tmp/*”);
Zakładam tu, iż na serwerze jest możliwe wykonywnie poleceń systemowych – efektem działania tego polecenia jest uzunięcie wszystkich plików sessji utworzonych przez serwer www w domyślnej lokalizacji.
Kolejnym efektem ubocznym działania trybu bezpiecznego jest konieczność wykonywania działań umożliwiających wykonywanie jego założeń tj. określenie pełnej ścieżki do pliku, oraz pobranie danych o właścicielu pliku (UID, GID), dodatkowo operacja ta może być wykonana na katalogu nadrzędnym co wymusza kolejną operacje. Tak więc w optymistycznym wariancie wykonywana jest jedna dodatkowa operacja systemowa, co gorsza operacja ta wykonywana jest dla każdego pliku na jakim operuje PHP i nie jest w żaden sposób cachowana pomiędzy wywołaniami. Operacje te nabierają na znaczeniu w sytuacji gdy mamy do czynienia z serwisem o znacznym obciążeniu , wymuszając wykonywanie setek dodatkowych operacji na sekundę.
Jak więc widzimy tryb safe_mode może spowodować spowolnienie działania aplikacji, utrudnić jej działanie nie podnosząc w żaden znaczący sposób poziom bezpieczeństwa. O wiele bardziej wydajną jak również chyba praktyczniejszą dyrektywą konfiguracyjną jest dyrektywa open_basedir ograniczająca zakres działania skryptów PHP do określonego katalogu(ów).
Dodatkowe informacje na temat trybu bezpiecznego można uzyskać pod adresem http://pl2.php.net/manual/en/features.safe-mode.php jak również w komentarzach zamieszczonych pod w/w adresem. Szczegółowe zagadnienia związane z bezpieczeństwem skryptów PHP zostały przedstawione w książce php|architect’s Guide to PHP Security