Capitolo 23. Modalità sicura (Safe mode)

Sommario
Funzioni limitate/disabilitate dalla modalità sicura (safe-mode)

La modalità Safe Mode è un tentativo di risolvere il problema di sicurezza derivante dalla condivisione del server. Dal punto di vista architetturale non è corretto cercare di risolvere questo problema al livello del PHP, ma poiché le alternative al livello del web server e del SO (Sistema Operativo) non sono realistiche, in molti, specialmente ISP (Internet Service Provider), utilizzano la modalità sicura.

Le direttive di configurazione che controllano la modalità sicura sono:

safe_mode = Off 
open_basedir = 
safe_mode_exec_dir = 
safe_mode_allowed_env_vars = PHP_ 
safe_mode_protected_env_vars = LD_LIBRARY_PATH 
disable_functions = 
   

Quando safe_mode è attiva (on), il PHP verifica se il proprietario dello script in esecuzione e il proprietario del file su cui si sta operando con una funzione sui file, coincidono. Per esempio:

-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 
   
Eseguendo questo script.php

<?php
 readfile('/etc/passwd'); 
?>  
   
con la modalità sicura attiva si ottiene il seguente errore:

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
   
Ovvero non è possibile accedere al file /etc/passwd in quanto l'utente che esegue lo script non coindice con l'utente proprietario del file.

Se, invece di safe_mode, viene definita una directory open_basedir allora tutte le operazioni sui file saranno limitate ai file sottostanti la directory specificata. Per esempio (nel file httpd.conf di Apache):

<Directory /docroot> 
php_admin_value open_basedir /docroot 
</Directory>  
   
Se si esegue lo stesso script.php con questa impostazione di open_basedir si ottiene il seguente risultato:

Warning: open_basedir restriction in effect. File is in wrong directory in 
/docroot/script.php on line 2 
   
Ovvero il file è in una directory non accessibile tramite script in PHP.

È possibile inoltre disabilitare le singole funzioni. Se si aggiunge la seguente riga al file php.ini:

disable_functions readfile,system  
   
Si ottiene il seguente risultato:

Warning: readfile() has been disabled for security reasons in 
/docroot/script.php on line 2 
   
Ovvero la funzione readfile() è stata disabilitata per motivi di sicurezza.

Funzioni limitate/disabilitate dalla modalità sicura (safe-mode)

Questo è un elenco probabilmente ancora incompleto e forse non esatto delle funzioni limitate da safe-mode.

Tabella 23-1. Funzioni limitate dalla modalità sicura

FunzioniLimitazioni
dbmopen()Controlla che i file e le directory su cui stai lavorando, abbiano lo stesso UID dello script che è in esecuzione.
dbase_open()Controlla che i file e le directory su cui stai lavorando, abbiano lo stesso UID dello script che è in esecuzione.
filepro()Controlla che i file e le directory su cui stai lavorando, abbiano lo stesso UID dello script che è in esecuzione.
filepro_rowcount()Controlla che i file e le directory su cui stai lavorando, abbiano lo stesso UID dello script che è in esecuzione.
filepro_retrieve()Controlla che i file e le directory su cui stai lavorando, abbiano lo stesso UID dello script che è in esecuzione.
ifx_*()sql_safe_mode restrictions, (!= Safe Mode)
ingres_*()sql_safe_mode restrictions, (!= Safe Mode)
mysql_*()sql_safe_mode restrictions, (!= Safe Mode)
pg_loimport()Controlla che i file e le directory su cui stai lavorando, abbiano lo stesso UID dello script che è in esecuzione.
posix_mkfifo()Controlla che la directory su cui stai lavorando, abbia lo stesso UID dello script che è in esecuzione.
putenv()??
move_uploaded_file()Controlla che i file e le directory su cui stai lavorando, abbiano lo stesso UID dello script che è in esecuzione.
chdir()Controlla che la directory su cui stai lavorando, abbia lo stesso UID dello script che è in esecuzione.
dl()??
shell_exec()??
popen()Controlla che la directory su cui stai lavorando, abbia lo stesso UID dello script che è in esecuzione.
mkdir()Controlla che la directory su cui stai lavorando, abbia lo stesso UID dello script che è in esecuzione.
rmdir()Controlla che i file e le directory su cui stai lavorando, abbiano lo stesso UID dello script che è in esecuzione.
rename()Controlla che i file e le directory su cui stai lavorando, abbiano lo stesso UID dello script che è in esecuzione.
unlink()Controlla che i file e le directory su cui stai lavorando, abbiano lo stesso UID dello script che è in esecuzione.
copy()Controlla che i file e le directory su cui stai lavorando, abbiano lo stesso UID dello script che è in esecuzione.
chgrp()Controlla che i file e le directory su cui stai lavorando, abbiano lo stesso UID dello script che è in esecuzione.
chown()Controlla che i file e le directory su cui stai lavorando, abbiano lo stesso UID dello script che è in esecuzione.
chmod()Controlla che i file e le directory su cui stai lavorando, abbiano lo stesso UID dello script che è in esecuzione.
touch()Controlla che i file e le directory su cui stai lavorando, abbiano lo stesso UID dello script che è in esecuzione.
symlink()Controlla che i file e le directory su cui stai lavorando, abbiano lo stesso UID dello script che è in esecuzione.
link()Controlla che i file e le directory su cui stai lavorando, abbiano lo stesso UID dello script che è in esecuzione.
getallheaders()??
exec()??
system()??
passthru()??
operatore backtick??
Qualsiasi funzione che utilizza php4/main/fopen_wrappers.c ??