0

0

PHP安全模式详解(PHP5.4安全模式将消失)

絕刀狂花

絕刀狂花

发布时间:2025-07-09 11:06:13

|

251人浏览过

|

来源于php中文网

原创

php安全模式详解(黄龟素)

这是之前的笔记,随笔分享。请注意,PHP安全模式在PHP 5.4版本中已不再支持。查看官方说明:

安全模式不再被支持。依赖安全模式的应用可能需要进行安全方面的调整。

  1. 安全模式

一直未使用过PHP的safe_mode安全模式,此笔记供日后参考。

PHP的安全模式旨在解决共享服务器(shared-server)的安全问题。尽管在结构上尝试在PHP层面上解决这个问题是不合理的,但修改Web服务器层和操作系统层显得不切实际。因此,许多人,尤其是ISP,目前采用安全模式。

立即学习PHP免费学习笔记(深入)”;

safe_mode是唯一具有PHP_INI_SYSTEM属性的设置,必须通过php.ini或httpd.conf来配置。要启用safe_mode,只需在php.ini中修改:safe_mode = On,或者在httpd.conf中定义目录:Options FollowSymLinks php_admin_value safe_mode 1,然后重启Apache,safe_mode即生效。

启用safe_mode后,将对许多PHP函数进行限制,特别是与系统相关的文件操作和命令执行函数。所有操作文件的函数只能操作与脚本UID相同的文件(脚本的UID不一定是运行Web服务器用户的UID)。

虽然safe_mode并非万能(低版本PHP可以绕过),但强烈建议开启安全模式,这在一定程度上可以避免一些未知的攻击。不过,启用safe_mode会带来许多限制,可能对应用产生影响,因此需要调整代码和配置以实现和谐。

安全模式配置指令:

名称 默认值 可修改范围 更新记录
safe_mode "0" PHP_INI_SYSTEM
safe_mode_gid "0" PHP_INI_SYSTEM 自PHP 4.1.0起可用
safe_mode_include_dir NULL PHP_INI_SYSTEM 自PHP 4.1.0起可用
safe_mode_exec_dir "" PHP_INI_SYSTEM
safe_mode_allowed_env_vars "PHP_" PHP_INI_SYSTEM
safe_mode_protected_env_vars "LD_LIBRARY_PATH" PHP_INI_SYSTEM
open_basedir NULL PHP_INI_SYSTEM
disable_functions "" 仅php.ini 自PHP 4.0.1起可用
disable_classes "" 仅php.ini 自PHP 4.3.2起可用
  1. 配置选项的简要解释

safe_mode boolean

是否启用PHP的安全模式。PHP的安全模式是一个非常重要的内置安全机制,可以控制一些PHP中的函数,比如system(),同时对许多文件操作函数进行权限控制,也不允许访问某些关键文件,如/etc/passwd。然而,默认的php.ini并未启用安全模式。我们可以将其开启:safe_mode = on,或者通过代码:

ini_set("safe_mode",true);

safe_mode_gid boolean

默认情况下,安全模式在打开文件时会进行UID比较检查。如果希望放宽到GID比较,则启用safe_mode_gid。用于文件访问时使用UID(FALSE)还是GID(TRUE)进行检查。

safe_mode_include_dir string

当从此目录及其子目录包含文件时(目录必须在include_path中或使用完整路径),将越过UID/GID检查。

自PHP 4.2.0起,本指令可以接受与include_path指令类似的风格,用冒号(Windows中为分号)分隔的路径,而不只是一个目录。

指定的限制实际上是前缀,而非目录名。例如,“safe_mode_include_dir = /dir/incl”将允许访问“/dir/include”和“/dir/incls”,如果它们存在的话。如果希望将访问限制在一个指定的目录,请在结尾加上斜线,例如:“safe_mode_include_dir = /dir/incl/”。

如果本指令的值为空,在PHP 4.2.3及PHP 4.3.3起,具有不同UID/GID的文件将不能被包含。在较早版本中,所有文件都能被包含。

safe_mode_exec_dir string

如果PHP使用了安全模式,system()和其他程序执行函数将拒绝启动不在此目录中的程序。必须使用/作为目录分隔符,包括Windows中。

safe_mode_allowed_env_vars string

设置某些环境变量可能是潜在的安全漏洞。本指令包含一个逗号分隔的前缀列表。在安全模式下,用户只能改变那些名称具有此处提供的前缀的环境变量。默认情况下,用户只能设置以PHP_开头的环境变量(例如PHP_FOO = BAR)。

safe_mode_protected_env_vars string

家饰网上商城系统
家饰网上商城系统

虚拟主机或在自备服务器中开设好的主机空间,主机环境要求:PHP4.3-5.x/非安全模式/允许WEB文件上传MYSQL4.2-5.xzend optimizer 3.2以上安装方法:1、将安装包解压后,将全部文件和目录上传到网站空间根目录, 用FTP上传时必须采用二进制方式。2、运行http://您的域名/(安装向导),或者进入网站安装http://您的域名/base/install/,填写MYS

下载

本指令包含一个逗号分隔的环境变量列表,最终用户不能用putenv()来改变这些环境变量。即使在safe_mode_allowed_env_vars中设置了允许修改,也不能改变这些变量。

open_basedir string

将PHP能够打开的文件限制在指定的目录树中,包括文件本身。本指令不受安全模式启用或关闭的影响。

当脚本试图使用例如fopen()或gzopen()打开文件时,该文件的位置将被检查。如果文件在指定的目录树之外,PHP将拒绝打开它。所有符号链接都会被解析,因此不可能通过符号链接来避开此限制。

特殊值.指明脚本的工作目录将被作为基准目录。但这有些危险,因为脚本的工作目录可以轻易被chdir()改变。

在httpd.conf文件中,open_basedir可以通过“php_admin_value open_basedir none”的方法关闭,例如某些虚拟主机中:

<directory>  php_admin_value open_basedir /docroot</directory>

在Windows中,用分号分隔目录。在其他系统中用冒号分隔目录。作为Apache模块时,父目录中的open_basedir路径自动被继承。

用open_basedir指定的限制实际上是前缀,不是目录名。也就是说,“open_basedir = /dir/incl”也会允许访问“/dir/include”和“/dir/incls”,如果它们存在的话。如果要将访问限制在仅为指定的目录,用斜线结束路径名。例如:“open_basedir = /dir/incl/”。

默认是允许打开所有文件。

disable_functions string

本指令允许您基于安全原因禁止某些函数。接受逗号分隔的函数名列表作为参数。disable_functions不受安全模式的影响。

本指令只能在php.ini中设置。例如,不能在httpd.conf中设置。

disable_classes string

本指令可以使您出于安全的理由禁用某些类。用逗号分隔类名。disable_classes不受安全模式的影响。

本指令只能在php.ini中设置。例如,不能在httpd.conf中设置。

expose_php = On/Off string

Server Apache/2.2.19 (Win32) PHP/5.3.8

PHP安全模式详解(PHP5.4安全模式将消失)

  1. 实战演示

当safe_mode设置为on时,PHP将通过文件函数或其目录检查当前脚本的拥有者是否与将被操作的文件的拥有者相匹配。例如:

4 -rw-r--r-- 1 httpd root    72 2012-04-16 00:51 test.php
4 -rw-r--r-- 1 root root 1853 2012-03-28 16:20 /etc/passwd

运行test.php:

<?php
fopen ('/etc/passwd','r');
readfile('/etc/passwd');
mkdir('test');
?>

如果安全模式被激活,则将会导致以下错误:

Warning: fopen() [function.fopen]: SAFE MODE Restriction in effect. The script whose uid is 1003 is not allowed to access /etc/passwd owned by uid 0 in /usr/local/httpd/htdocs/test.php on line 2
Warning: fopen(/etc/passwd) [function.fopen]: failed to open stream: Inappropriate ioctl for device in /usr/local/httpd/htdocs/test.php on line 2
Warning: readfile() [function.readfile]: SAFE MODE Restriction in effect. The script whose uid is 1003 is not allowed to access /etc/passwd owned by uid 0 in /usr/local/httpd/htdocs/test.php on line 3
Warning: readfile(/etc/passwd) [function.readfile]: failed to open stream: Inappropriate ioctl for device in /usr/local/httpd/htdocs/test.php on line 3

也可以单独地屏蔽某些函数。请注意disable_functions选项不能在php.ini文件外部使用,也就是说无法在httpd.conf文件的按不同虚拟主机或不同目录的方式来屏蔽函数。如果将如下内容加入到php.ini文件:

disable_functions readfile,system

则会得到如下的输出:

Warning: readfile() has been disabled for security reasons in /usr/local/httpd/htdocs/test.php on line 3
  1. 安全模式限制函数
函数名 限制
dbmopen() 检查被操作的文件或目录是否与正在执行的脚本有相同的UID(所有者)。
dbase_open() 检查被操作的文件或目录是否与正在执行的脚本有相同的UID(所有者)。
filepro() 检查被操作的文件或目录是否与正在执行的脚本有相同的UID(所有者)。
filepro_rowcount() 检查被操作的文件或目录是否与正在执行的脚本有相同的UID(所有者)。
filepro_retrieve() 检查被操作的文件或目录是否与正在执行的脚本有相同的UID(所有者)。
ifx_* sql_safe_mode限制,(!= safe mode)
ingres_* sql_safe_mode限制,(!= safe mode)
mysql_* sql_safe_mode限制,(!= safe mode)
pg_loimport() 检查被操作的文件或目录是否与正在执行的脚本有相同的UID(所有者)。
posix_mkfifo() 检查被操作的目录是否与正在执行的脚本有相同的UID(所有者)。
putenv() 遵循ini设置的safe_mode_protected_env_vars和safe_mode_allowed_env_vars选项。请参考putenv()函数的有关文档。
move_uploaded_file() 检查被操作的文件或目录是否与正在执行的脚本有相同的UID(所有者)。
chdir() 检查被操作的目录是否与正在执行的脚本有相同的UID(所有者)。
dl() 本函数在安全模式下被禁用。
backtick operator 本函数在安全模式下被禁用。
shell_exec() 本函数在安全模式下被禁用。
exec() 只能在safe_mode_exec_dir设置的目录下进行执行操作。基于某些原因,目前不能在可执行对象的路径中使用..。escapeshellcmd()将被作用于此函数的参数上。
system() 只能在safe_mode_exec_dir设置的目录下进行执行操作。基于某些原因,目前不能在可执行对象的路径中使用..。escapeshellcmd()将被作用于此函数的参数上。
passthru() 只能在safe_mode_exec_dir设置的目录下进行执行操作。基于某些原因,目前不能在可执行对象的路径中使用..。escapeshellcmd()将被作用于此函数的参数上。
popen() 只能在safe_mode_exec_dir设置的目录下进行执行操作。基于某些原因,目前不能在可执行对象的路径中使用..。escapeshellcmd()将被作用于此函数的参数上。
fopen() 检查被操作的目录是否与正在执行的脚本有相同的UID(所有者)。
mkdir() 检查被操作的目录是否与正在执行的脚本有相同的UID(所有者)。
rmdir() 检查被操作的目录是否与正在执行的脚本有相同的UID(所有者)。
rename() 检查被操作的文件或目录是否与正在执行的脚本有相同的UID(所有者)。检查被操作的目录是否与正在执行的脚本有相同的UID(所有者)。
unlink() 检查被操作的文件或目录是否与正在执行的脚本有相同的UID(所有者)。检查被操作的目录是否与正在执行的脚本有相同的UID(所有者)。
copy() 检查被操作的文件或目录是否与正在执行的脚本有相同的UID(所有者)。检查被操作的目录是否与正在执行的脚本有相同的UID(所有者)。(源文件和目标文件)
chgrp() 检查被操作的文件或目录是否与正在执行的脚本有相同的UID(所有者)。
chown() 检查被操作的文件或目录是否与正在执行的脚本有相同的UID(所有者)。
chmod() 检查被操作的文件或目录是否与正在执行的脚本有相同的UID(所有者)。另外,不能设置SUID、SGID和sticky bits。
touch() 检查被操作的文件或目录是否与正在执行的脚本有相同的UID(所有者)。检查被操作的目录是否与正在执行的脚本有相同的UID(所有者)。
symlink() 检查被操作的文件或目录是否与正在执行的脚本有相同的UID(所有者)。检查被操作的目录是否与正在执行的脚本有相同的UID(所有者)。(注意:仅测试目标)
link() 检查被操作的文件或目录是否与正在执行的脚本有相同的UID(所有者)。检查被操作的目录是否与正在执行的脚本有相同的UID(所有者)。(注意:仅测试目标)
apache_request_headers() 在安全模式下,以“authorization”(区分大小写)开头的标头将不会被返回。
header() 在安全模式下,如果设置了WWW-Authenticate,当前脚本的UID将被添加到该标头的realm部分。
PHP_AUTH变量 在安全模式下,变量PHP_AUTH_USER、PHP_AUTH_PW和PHP_AUTH_TYPE在$_SERVER中不可用。但无论如何,您仍然可以使用REMOTE_USER来获取用户名称(USER)。(注意:仅PHP 4.3.0以后有效)
highlight_file(), show_source() 检查被操作的文件或目录是否与正在执行的脚本有相同的UID(所有者)。检查被操作的目录是否与正在执行的脚本有相同的UID(所有者)。(注意,仅在4.2.1版本后有效)
parse_ini_file() 检查被操作的文件或目录是否与正在执行的脚本有相同的UID(所有者)。检查被操作的目录是否与正在执行的脚本有相同的UID(所有者)。(注意,仅在4.2.1版本后有效)
set_time_limit() 在安全模式下不起作用。
max_execution_time 在安全模式下不起作用。
mail() 在安全模式下,第五个参数被屏蔽。(注意,仅自PHP 4.2.3起受影响)

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

1010

2023.08.02

java中boolean的用法
java中boolean的用法

在Java中,boolean是一种基本数据类型,它只有两个可能的值:true和false。boolean类型经常用于条件测试,比如进行比较或者检查某个条件是否满足。想了解更多java中boolean的相关内容,可以阅读本专题下面的文章。

367

2023.11.13

java boolean类型
java boolean类型

本专题整合了java中boolean类型相关教程,阅读专题下面的文章了解更多详细内容。

42

2025.11.30

windows查看端口占用情况
windows查看端口占用情况

Windows端口可以认为是计算机与外界通讯交流的出入口。逻辑意义上的端口一般是指TCP/IP协议中的端口,端口号的范围从0到65535,比如用于浏览网页服务的80端口,用于FTP服务的21端口等等。怎么查看windows端口占用情况呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

1496

2023.07.26

查看端口占用情况windows
查看端口占用情况windows

端口占用是指与端口关联的软件占用端口而使得其他应用程序无法使用这些端口,端口占用问题是计算机系统编程领域的一个常见问题,端口占用的根本原因可能是操作系统的一些错误,服务器也可能会出现端口占用问题。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

1170

2023.07.27

windows照片无法显示
windows照片无法显示

当我们尝试打开一张图片时,可能会出现一个错误提示,提示说"Windows照片查看器无法显示此图片,因为计算机上的可用内存不足",本专题为大家提供windows照片无法显示相关的文章,帮助大家解决该问题。

835

2023.08.01

windows查看端口被占用的情况
windows查看端口被占用的情况

windows查看端口被占用的情况的方法:1、使用Windows自带的资源监视器;2、使用命令提示符查看端口信息;3、使用任务管理器查看占用端口的进程。本专题为大家提供windows查看端口被占用的情况的相关的文章、下载、课程内容,供大家免费下载体验。

463

2023.08.02

windows无法访问共享电脑
windows无法访问共享电脑

在现代社会中,共享电脑是办公室和家庭的重要组成部分。然而,有时我们可能会遇到Windows无法访问共享电脑的问题。这个问题可能会导致数据无法共享,影响工作和生活的正常进行。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2361

2023.08.08

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

3

2026.03.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PHP课程
PHP课程

共137课时 | 13.4万人学习

JavaScript ES5基础线上课程教学
JavaScript ES5基础线上课程教学

共6课时 | 11.3万人学习

PHP新手语法线上课程教学
PHP新手语法线上课程教学

共13课时 | 1.0万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号