安全模式

Table of Contents

PHP 的安全模式是为了试图解决共享服务器(shared-server)安全问题而设立的。在结构上,试图在 PHP 层上解决这个问题是不合理的,但修改 web 服务器层和操作系统层显得非常不现实。因此许多人,特别是 ISP,目前使用安全模式。

Warning

本特性已自 PHP 5.3.0 起废弃并将自 PHP 5.4.0 起移除

Changelog for safe mode
版本 说明
5.4.0 Removed from PHP, and generates a fatal E_CORE_ERROR level error when enabled.
5.3.0 Deprecated, and E_DEPRECATED errors were added.

User Contributed Notes

bsd912 at 163 dot com 15-May-2018 01:17
When in safe mode, mkdir creates folders with apache's UID, though the files you create in them are of your script's UID (usually the same as your FTP uid).

What this means is that if you create a folder, you won't be able to remove it, nor to remove any of the files you've created in it (because those operations require the UID to be the same).

Ideally mkdir should create the folder with the script's UID, but this has already been discussed and will not be fixed in the near future.

And my solution to fix this problem is:
1. You need append the apache group to your script's UID.
2. Turn on safe_mode_gid in the php.ini
3. Chgrp the script to apache, but don't change the UID
4. Now you can use safe_mode and mkdir now.
14-Sep-2006 10:18
Each IIS server in Windows runs as a User so it does have a UID file ACLs can be applied via a Group (GID) or User.  The trick is to configure each website to run as a distinct user instead of the default of System.
martin at example dot com 01-Nov-2005 04:07
On the note of php security

have a look at: http://www.suphp.org/Home.html

 suPHP is a tool for executing PHP scripts with the permissions of their owners. It consists of an Apache module (mod_suphp) and a setuid root binary (suphp) that is called by the Apache module to change the uid of the process executing the PHP interpreter.
jo at durchholz dot org 18-Jul-2005 01:18
Note that safe mode is largely useless. Most ISPs that offer Perl also offer other scripting languages (mostly Perl), and these other languages don't have the equivalent of PHP.
In other words, if PHP's safe mode won't allow vandals into your web presence, they will simply use Perl.
Also, safe mode prevents scripts from creating and using directories (because they will be owned by the WWW server, not by the user who uploaded the PHP script). So it's not only useless, it's also a hindrance.
The only realistic option is to bugger the Apache folks until they run all scripts as the user who's responsible for a given virtualhost or directory.
03-May-2005 09:37
To separate distinct open_basedir use : instead of on , or ; on unix machines.
plyrvt at mail dot ru 29-Apr-2005 03:14
[In reply to jedi at tstonramp dot com]
Safe mode is used "since the alternatives at the web server and OS levels aren't very realistic". Manual says about UNIX OS level and UNIX web-servers by design (Apache). It's not realistic for unix-like server, but for NT (IIS) each virtual host can run from different user account, so there is no need in Safe Mode restrictions at all, if proper NTFS rights are set.
bertrand dot gorge at epistema dot com 23-Sep-2004 05:58
Beware that when in safe mode, mkdir creates folders with apache's UID, though the files you create in them are of your script's UID (usually the same as your FTP uid).

What this means is that if you create a folder, you won't be able to remove it, nor to remove any of the files you've created in it (because those operations require the UID to be the same).

Ideally mkdir should create the folder with the script's UID, but this has already been discussed and will not be fixed in the near future.

In the meantime, I would advice NOT to user mkdir in safe mode, as you may end up with folders you can't remove/use.
Russ 31-Aug-2004 08:52
Sometimes you're stuck on a system you don't run and you can't control the setting of safe mode.  If your script needs to run on different hosts (some with safe mode, some without it), you can code around it with something like:

<?php
// Check for safe mode
if( ini_get('safe_mode') ){
   
// Do it the safe mode way
}else{
   
// Do it the regular way
}

?>
daniel dot gaddis at tlc dot state dot tx dot us 17-Mar-2004 11:03
on windows if multiple directories are wanted for safe_mode_exec_dir and open_basedir be sure to separate the paths with a semi colon and double quote the whole path string. For example:

safe_mode = On
safe_mode_exec_dir = "F:\WWW\HTML;F:\batfiles\batch"
open_basedir = "F:\WWW\HTML;F:\batfiles\batch"
info at phpcoding dot net 08-Mar-2003 06:44
readfile() seems not always to take care of the safe_mode setting.
When the file you want to read with readfile() resides in the same directory as the script itself, it doesn`t matter who the owner of the file is, readfile() will work.
gtg782a at mail dot gatech dot edu 26-Jan-2003 09:14
zebz: The user would not be able to create a directory outside the namespace where he/she would be able to modify its contents. One can't create a directory that becomes apache-owned unless one owns the parent directory.

Another security risk: since files created by apache are owned by apache, a user could call the fputs function and output PHP code to a newly-created file with a .php extension, thus creating an apache-owned PHP script on the server. Executing that apache-owned script would allow the script to work with files in the apache user's namespace, such as logs. A solution would be to force PHP-created files to be owned by the same owner/group as the script that created them. Using open_basedir would be a likely workaround to prevent ascension into uncontrolled areas.
zebz at ihaveenoughspam_hotmail dot com 28-Apr-2002 08: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.
devik at cdi dot cz 24-Jan-2002 04: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
jedi at tstonramp dot com 07-Sep-2001 07: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.