Tryb bezpieczny (ang. safe mode) jest próbą rozwiązania problemów bezpieczeństwa na współdzielonym serwerze. Co prawda rozwiązywanie ich na poziomie PHP nie jest najlepszym rozwiązaniem, ale jeśli nie ma możliwości zrobienia tego na poziomie serwera www lub systemu operacyjnego, na wielu serwerach, zwłaszcza u usługodawców internetowych, używa się trybu bezpiecznego.
Tryb bezpieczny został usunięty w PHP 6.0.0.
Nazwa | Wartość domyślna | Możliwość zmian | Rejestr zmian |
---|---|---|---|
safe_mode | "0" | PHP_INI_SYSTEM | Usunięta w PHP 6.0.0. |
safe_mode_gid | "0" | PHP_INI_SYSTEM | Dostępna od PHP 4.1.0. Usunięta w PHP 6.0.0. |
safe_mode_include_dir | NULL | PHP_INI_SYSTEM | Dostępna od PHP 4.1.0. Usunięta w PHP 6.0.0. |
safe_mode_exec_dir | "" | PHP_INI_SYSTEM | Usunięta w PHP 6.0.0. |
safe_mode_allowed_env_vars | "PHP_" | PHP_INI_SYSTEM | Usunięta w PHP 6.0.0. |
safe_mode_protected_env_vars | "LD_LIBRARY_PATH" | PHP_INI_SYSTEM | Usunięta w PHP 6.0.0. |
open_basedir | NULL | PHP_INI_ALL | PHP_INI_SYSTEM w PHP < 6. |
disable_functions | "" | tylko php.ini | Dostępna od PHP 4.0.1. |
disable_classes | "" | tylko php.ini | Dostępna od PHP 4.3.2. |
Oto krótkie wyjaśnienie dyrektyw konfiguracji.
Określa czy należy włączyć w PHP tryb bezpieczny.
Domyślnie tryb bezpieczny sprawdza, czy właścicielem uruchamianego skryptu lub pliku, do którego funkcja chce uzyskać dostęp, jest ten sam użytkownik (UID). Jeśli chcemy aby porównywana dotyczyły całej grupy (GID), należy włączyć safe_mode_gid. Określa czy używać UID (FALSE) lub GID (TRUE) podczas sprawdzania dostępu do pliku.
Sprawdza czy nie nastąpiło obejście UID/GID podczas dołączania plików z tego katalogu i jego podkatalogów (ścieżka do katalogu powinna być podana w include_path lub też powinna być dołączona pełna nazwa ścieżki).
Od PHP 4.2.0 ta dyrektywa może zawierać dwukropek (w Windows średnik) oddzielający ścieżki, podobnie jak w przypadku dyrektywy include_path, a nie tylko pojedyńczy katalog. Rejestrowanie ścieżki określane jest obecnie przez przedrostek, a nie nazwę katalogu. To oznacza, że "safe_mode_include_dir = /dir/incl" pozwala uzyskać dostęp do "/dir/include" i "/dir/incls" (jeżeli istnieją). Gdy chcemy ograniczyć dostęp tylko do określonego katalogu, dodajemy na końcu ukośnik. Na przykład: "safe_mode_include_dir = /dir/incl/" Jeśli wartość dyrektywy jest pusta, to żadne pliki - inne niż należące do UID/GID nie mogą być dołączone (w PHP 4.2.3 i od PHP 4.3.3). We wcześniejszych wersjach mogły być dołączane wszystkie pliki.Jeśli PHP działa w trybie bezpiecznym, system() i inne funkcje wykonujące programy systemowe otrzymają odmowę uruchomienia programów, tych które nie znajdują się w tym katalogu. Używamy / jako separatora katalogu dla wszystkich środowisk, włącznie z Windows.
Ustawienie pewnych zmiennych środowiskowych może być potencjalnym naruszeniem bezpieczeństwa. Ta dyrektywa zawiera listę przedrostków oddzielonych przecinkami. W trybie bezpiecznym użytkownik może wyłącznie zmieniać zmienne środowiskowe, których nazwy zaczynają się od przedrostków tutaj wymienionych. Domyślnie użytkownicy mają tylko możliwość ustawiania zmiennych środowiskowych zaczynających się od PHP_ (np. PHP_FOO=BAR).
Informacja: Jeśli ta dyrektywa jest pusta, PHP pozwoli użytkownikowi zmieniać WSZYSTKIE zmienne środowiskowe!
Ta dyretywa zawiera listę zmiennych środowiskowych oddzielonych przecinkami, których użytkownik końcowy nie może zmienić za pomocą putenv(). Te zmienne są zawsze chronione nawet jeśli safe_mode_allowed_env_vars pozwala na ich zmianę.
Ograniczenie dla plików polegające na tym, że mogą one być otwierane przez PHP wyłącznie w określonem drzewie katalogów. Działanie tej dyrektywy NIE zależy od tego czy tryb bezpieczny jest włączony czy wyłączony.
Gdy skrypt próbuje otworzyć plik za pomocą np. fopen() lub gzopen(), sprawdzana jest lokalizacja tego pliku. Jeśli plik znajduje się poza określonym drzewem katalogów, wtedy PHP odmówi dostępu do otwarcia go. Wszystkie dowiązania symboliczne są sprawdzane, tak więc nie jest możliwe obejście tej restrykcji za pomocą dowiązań symbolicznych. Jeśli plik nie istnieje wówczas dowiązanie symboliczne nie może być sprawdzone, a pełna ścieżka nazwy pliku jest porównywana z open_basedir .
Specjalna wartość .
wskazuje, że roboczy katalog skryptu ma być traktowany jako katalog
podstawowy. To jest jednakże nieco niebezpieczne, jako że katalog roboczy
skryptu można łatwo zmienić za pomocą chdir().
W httpd.conf, open_basedir może być wyłączony (np. dla niektórych hostów wirtualnych) ten sam efekt uzyskamy za pomocą innej dyrektywy konfiguracyjnej: "php_admin_value open_basedir none".
W Windows oddzielamy katalogi za pomocą średnika, natomiast we wszystkich innych systemach operacyjnych za pomocą dwukropka. Gdy PHP działa jako moduł serwera Apache, ścieżki open_basedir z katalogów nadrzędnych są automatycznie dziedziczone.
Restrykcja określona za pomocą open_basedir jest obecnie przedrostkiem a nie nazwą katalogu. To oznacza, że "open_basedir = /dir/incl" pozwala uzyskać dostęp do "/dir/include" i "/dir/incls" (jeżeli istnieją). Gdy chcemy ograniczyć dostęp tylko do określonego katalogu, dodajemy na końcu ukośnik. Na przykład: "open_basedir = /dir/incl/"
Domyślnie PHP ma dostęp do plików we wszystkich lokalizacjach.
Informacja: Availability note
Ta dyrektywa została dodana w PHP 4.3.2
Patrz także: register_globals, display_errors, i log_errors.
Gdy opcja safe_mode jest włączona, PHP sprawdza czy właścicielem wykonywanego skryptu jest właściciel pliku, na którym chce operować funkcja, lub czy jest to katalog tego samego użytkownika. Na Przykład:
-rw-rw-r-- 1 rasmus rasmus 33 Jul 1 19:20 script.php -rw-r--r-- 1 root root 1116 May 26 18:01 /etc/passwd
<?php
readfile('/etc/passwd');
?>
Warning: SAFE MODE Restriction in effect. The script whose uid is 500 is not allowed to access /etc/passwd owned by uid 0 in /docroot/script.php on line 2
Jednakże mogą być środowiska, gdzie zbyt restrykcyjna weryfikacja UID nie jest stosownym rozwiązaniem, a łagodniejsze sprawdzanie GID jest w pełni wystarczające. Można to zmienić za pomocą safe_mode_gid. Ustawienie tej opcji na On włącza łagodniejsze sprawdzanie GID, a ustawienie na Off (domyślnie) przełącza na sprawdzanie UID.
Jeśli zamiast safe_mode ustawiamy katalog open_basedir wtedy wszystkie operacje na plikach będą ograniczone do plików znajdujących się w nim. Na przykład (Apache httpd.conf):
<Directory /docroot> php_admin_value open_basedir /docroot </Directory>
Warning: open_basedir restriction in effect. File is in wrong directory in /docroot/script.php on line 2
Możemy wyłączyć obsługę wybranych funkcji. Zauważmy, że dyrektywa disable_functions nie może być ustawiana poza plikiem php.ini co oznacza, że nie możemy wyłączyć funkcji dla wybranego wirtualnego hosta lub katalogu zdefiniowanego w pliku httpd.conf. Jeśli dodamy następującą dyrektywę do naszego pliku php.ini:
disable_functions = readfile,system
Warning: readfile() has been disabled for security reasons in /docroot/script.php on line 2
Naturalnie restrykcje PHP nie obowiązują w plikach wykonywalnych.