PHP  
downloads | documentation | faq | getting help | | php.net sites | links 
search for in the  
previousPersistent Database ConnectionsUsing PHP from the command linenext
Last updated: Tue, 28 May 2002
view this page in Printer friendly version | English | Brazilian Portuguese | Czech | Dutch | French | German | Hungarian | Italian | Japanese | Korean | Polish | Romanian | Russian | Spanish | Turkish

Luku 23. Safe Mode

The PHP safe mode is an attempt to solve the shared-server security problem. It is architecturally incorrect to try to solve this problem at the PHP level, but since the alternatives at the web server and OS levels aren't very realistic, many people, especially ISP's, use safe mode for now.

Taulu 23-1. Configuration directives controlling safe mode are:

DirectiveDefault value
safe_mode Off
safe_mode_gid 0
safe_mode_include_dir ""
safe_mode_exec_dir 1
open_basedir ""
safe_mode_allowed_env_vars PHP_
safe_mode_protected_env_vars LD_LIBRARY_PATH
disable_functions ""

When safe_mode is on, PHP checks to see if the owner of the current script matches the owner of the file to be operated on by a file function. For example:

-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
Running this script.php
<?php
 readfile('/etc/passwd'); 
?>
results in this error when safe mode is enabled:
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

However, there may be environments where a strict UID check is not appropriate and a relaxed GID check is sufficient. This is supported by means of the safe_mode_gid switch. Setting it to On performs the relaxed GID checking, setting it to Off (the default) performs UID checking.

If instead of safe_mode, you set an open_basedir directory then all file operations will be limited to files under the specified directory For example (Apache httpd.conf example):

<Directory /docroot>
  php_admin_value open_basedir /docroot 
</Directory>
If you run the same script.php with this open_basedir setting then this is the result:
Warning: open_basedir restriction in effect. File is in wrong directory in 
/docroot/script.php on line 2

You can also disable individual functions. Note that the disable_functions directive can not be used outside of the php.ini file which means that you cannot disable functions on a per-virtualhost or per-directory basis in your httpd.conf file. If we add this to our php.ini file:

disable_functions readfile,system
Then we get this output:
Warning: readfile() has been disabled for security reasons in 
/docroot/script.php on line 2

Functions restricted/disabled by safe mode

This is a still probably incomplete and possibly incorrect listing of the functions limited by safe mode.

Taulu 23-2. Safe mode limited functions

FunctionLimitations
dbmopen()Tarkistaa onko k�sitelt�vill� tiedostoilla/hakemistoilla sama UID kuin ajettavalla skriptill�.
dbase_open()Tarkistaa onko k�sitelt�vill� tiedostoilla/hakemistoilla sama UID kuin ajettavalla skriptill�.
filepro()Tarkistaa onko k�sitelt�vill� tiedostoilla/hakemistoilla sama UID kuin ajettavalla skriptill�.
filepro_rowcount()Tarkistaa onko k�sitelt�vill� tiedostoilla/hakemistoilla sama UID kuin ajettavalla skriptill�.
filepro_retrieve()Tarkistaa onko k�sitelt�vill� tiedostoilla/hakemistoilla sama UID kuin ajettavalla skriptill�.
ifx_*()sql_safe_mode restrictions, (!= safe mode)
ingres_*()sql_safe_mode restrictions, (!= safe mode)
mysql_*()sql_safe_mode restrictions, (!= safe mode)
pg_loimport()Tarkistaa onko k�sitelt�vill� tiedostoilla/hakemistoilla sama UID kuin ajettavalla skriptill�.
posix_mkfifo()Tarkistaa onko hakemistolla, jossa operoidaan, sama UID kuin ajettavalla skriptill�.
putenv()Obeys the safe_mode_protected_env_vars and safe_mode_allowed_env_vars ini-directives. See also the documentation on putenv()
move_uploaded_file()Tarkistaa onko k�sitelt�vill� tiedostoilla/hakemistoilla sama UID kuin ajettavalla skriptill�.
chdir()Tarkistaa onko hakemistolla, jossa operoidaan, sama UID kuin ajettavalla skriptill�.
dl()T�m� funktio ei ole k�yt�ss� jos safe mode on kytketty p��lle.
backtick operatorT�m� funktio ei ole k�yt�ss� jos safe mode on kytketty p��lle.
shell_exec() (functional equivalent of backticks)T�m� funktio ei ole k�yt�ss� jos safe mode on kytketty p��lle.
exec()You can only execute executables within the safe_mode_exec_dir. For practical reasons it's currently not allowed to have .. components in the path to the executable.
system()You can only execute executables within the safe_mode_exec_dir. For practical reasons it's currently not allowed to have .. components in the path to the executable.
passthru()You can only execute executables within the safe_mode_exec_dir. For practical reasons it's currently not allowed to have .. components in the path to the executable.
popen()You can only execute executables within the safe_mode_exec_dir. For practical reasons it's currently not allowed to have .. components in the path to the executable.
mkdir()Tarkistaa onko hakemistolla, jossa operoidaan, sama UID kuin ajettavalla skriptill�.
rmdir()Tarkistaa onko k�sitelt�vill� tiedostoilla/hakemistoilla sama UID kuin ajettavalla skriptill�.
rename()Tarkistaa onko k�sitelt�vill� tiedostoilla/hakemistoilla sama UID kuin ajettavalla skriptill�. Tarkistaa onko hakemistolla, jossa operoidaan, sama UID kuin ajettavalla skriptill�.
unlink()Tarkistaa onko k�sitelt�vill� tiedostoilla/hakemistoilla sama UID kuin ajettavalla skriptill�. Tarkistaa onko hakemistolla, jossa operoidaan, sama UID kuin ajettavalla skriptill�.
copy()Tarkistaa onko k�sitelt�vill� tiedostoilla/hakemistoilla sama UID kuin ajettavalla skriptill�. Tarkistaa onko hakemistolla, jossa operoidaan, sama UID kuin ajettavalla skriptill�. (on source and target)
chgrp()Tarkistaa onko k�sitelt�vill� tiedostoilla/hakemistoilla sama UID kuin ajettavalla skriptill�.
chown()Tarkistaa onko k�sitelt�vill� tiedostoilla/hakemistoilla sama UID kuin ajettavalla skriptill�.
chmod()Tarkistaa onko k�sitelt�vill� tiedostoilla/hakemistoilla sama UID kuin ajettavalla skriptill�. In addition, you cannot set the SUID, SGID and sticky bits
touch()Tarkistaa onko k�sitelt�vill� tiedostoilla/hakemistoilla sama UID kuin ajettavalla skriptill�. Tarkistaa onko hakemistolla, jossa operoidaan, sama UID kuin ajettavalla skriptill�.
symlink()Tarkistaa onko k�sitelt�vill� tiedostoilla/hakemistoilla sama UID kuin ajettavalla skriptill�. Tarkistaa onko hakemistolla, jossa operoidaan, sama UID kuin ajettavalla skriptill�. (note: only the target is checked)
link()Tarkistaa onko k�sitelt�vill� tiedostoilla/hakemistoilla sama UID kuin ajettavalla skriptill�. Tarkistaa onko hakemistolla, jossa operoidaan, sama UID kuin ajettavalla skriptill�. (note: only the target is checked)
getallheaders()In safe mode, headers beginning with 'authorization' (case-insensitive) will not be returned. Warning: this is broken with the aol-server implementation of getallheaders()!
header()In safe mode, the uid of the script is added to the realm part of the WWW-Authenticate header if you set this header (used for HTTP Authentication).
highlight_file(), show_source() Tarkistaa onko k�sitelt�vill� tiedostoilla/hakemistoilla sama UID kuin ajettavalla skriptill�. Tarkistaa onko hakemistolla, jossa operoidaan, sama UID kuin ajettavalla skriptill�. (note: only affected since PHP 4.2.1)
parse_ini_file() Tarkistaa onko k�sitelt�vill� tiedostoilla/hakemistoilla sama UID kuin ajettavalla skriptill�. Tarkistaa onko hakemistolla, jossa operoidaan, sama UID kuin ajettavalla skriptill�. (note: only affected since PHP 4.2.1)
Any function that uses php4/main/fopen_wrappers.c ??

User Contributed Notes
Safe Mode
add a note about notes
Marc Delisle
16-Jul-2001 09:49

include() and require() are also limited by safe mode.


08-Sep-2001 01:17

Many filesystem-related functions are not appropriately restricted when
Safe Mode is activated on an NT server it seems.  I would assume that this
is due to the filesystem not making use of UID.

In all of my scripts, no matter WHO owns the script (file Ownership-wise)
or WHO owns the directory/file in question; both UIDs display

(getmyuid() and fileowner()) as UID = 0

This has the rather nasty side effect of Safe Mode allowing multiple
filesystem operations because it believes the script owner and file/dir
owner are one and the same.

While this can be worked around by the judicious application of proper
filesystem privileges, it's still a "dud" that many of Safe
Mode's securities are simply not there with an NT implementation.

phobo#paradise.net.nz
03-Oct-2001 01:21

If you do virutal hosting, you can turn safe mode on and off for different
Apache Virutal Hosts using the php_admin_value directive. This also allows
you to have customised maximum execution times, disabled functions, etc.
By placeing a base_dir for each virutal host, this means PHP CANNOT access
files below this heirachy; strongly recoomended for cutsomer hosting.

Eg:

[VirtualHost 127.0.0.1:80]
   DocumentRoot /var/www/html/safephphost/
   ServerName safephp
   php_admin_value safe_mode 1
   php_admin_value open_basedir /var/www/html/safephphost/
   php_admin_value sendmail_from phobo#paradise.net.nz
[/VirtualHost]


24-Jan-2002 10:45

Just to note, I created patch which allows VirtualHost to set User under
which all (PHP too) runs. It is more secure than safe_mode. See
luxik.cdi.cz/~devik/apache/ if you are interested


28-Apr-2002 02:42

All the filesystem-related functions (unlink, fopen, unlink, etc) seems to
be restricted the same way in safe mode, at least on PHP 4.2. If the file
UID is different *but* the directory (where the file is located) UID is
the same, it will work.

So creating a directory in safe mode is usually a bad idea since the UID
will be different from the script (it will be the apache UID) so it won't
be possible to do anything with the files created on this directory.


01-Jun-2002 11:11

This is just a reply to phobo#paradise.net.nz about the virtual server. 
This no longer works on apache, if you do try you will get:
Syntax error on line 1118 of /usr/www/conf/httpd.conf:
php_admin_value not allowed here


13-Jun-2002 09:37

You can a vhost.conf file.

<Directory /vhosts/domain.com/httpdocs/> 
php_admin_value safe_mode 0
php_admin_value open_basedir "/"
</Directory>

19-Jun-2002 08:44
disable_functions must use "=" operator to assign value. Please
correct exemple.

add a note about notes
previousPersistent Database ConnectionsUsing PHP from the command linenext
Last updated: Tue, 28 May 2002
show source | credits | stats | mirror sites:  
Copyright © 2001, 2002 The PHP Group
All rights reserved.
This mirror generously provided by:
Last updated: Thu Jul 4 12:06:15 2002 CEST