解读php核心配置文件最好的资料就是php手册(官方文档),php中文手册地址如下
PHP Manual | PHP 中文手册 (golaravel.com)
后面对配置的解析基本都会加上官方文档的链接
参考文章 :
PHP代码审计一(PHP核心配置详解)_safe_moade_exec_dir-CSDN博客
safe_mode(php安全模式) - mrhonest - 博客园 (cnblogs.com)
获取配置信息的方式
在解析php配置文件时,先来浅谈一下获取php配置信息的方式
- 首先肯定是最熟悉的
phpinfo()
,不多介绍 - ini_get(): 用于获取当前 PHP 配置选项的值。可以通过传递配置选项的名称作为参数来获取相应的配置值。
- get_cfg_var(): 类似于
ini_get()
,用于获取配置选项的值。它也可以用于获取配置文件中的设置。 - ini_set(): 用于在运行时设置 PHP 配置选项的值。需要注意的是,并非所有配置选项都可以在运行时更改,而且在某些环境中可能会被禁用。
对于获取php配置选项使用的函数ini_get()
,在官方手册中没有明确的定义范围
但是对于修改配置信息ini_set()
,官方手册明确定义了php配置选项的可修改范围,每一个配置选项都有其可修改范围,定义如下
运行时配置 « PHP Manual | PHP 中文手册 (golaravel.com)
PHP_INI_* 模式的定义
模式 | 含义 |
---|---|
PHP_INI_USER | 可在用户脚本(例如 ini_set())或 Windows 注册表(自 PHP 5.3 起)以及 .user.ini 中设定 |
PHP_INI_PERDIR | 可在 php.ini,.htaccess 或 httpd.conf 中设定 |
PHP_INI_SYSTEM | 可在 php.ini 或 httpd.conf 中设定 |
PHP_INI_ALL | 可在任何地方设定 |
例如 output_buffering 指令是属于 PHP_INI_PERDIR,因而就不能用 ini_set() 来设定。但是 display_errors 指令是属于 PHP_INI_ALL 因而就可以在任何地方被设定,包括 ini_set()。
官方手册对php配置选项中,也给出了选项的修改范围,可自行查询
open_basedir
open_basedir能限制应用程序能访问的目录。将PHP所能打开的文件限制在指定的目录树中,包括文件本身。当程序要使用例如fopen()或file_get_contents()打开一个文件时,这个文件的位置将会被检查。当文件在指定的目录树之外,程序将拒绝打开。检查有没有对open_basedir进行设置,当然有的通过web服务器来设置,例如:apache的php_admin_value,nginx+fcgi通过conf来控制。
通常我们只需要设置为web目录就可以了,如果需要加载外部脚本,也需要把脚本所在目录路径加入到open_basedir指令中,多个目录以分号(; )分割。使用open_basedir 需要注意的一点是,指定的限
制实际上是前缀,而不是目录名。例如,如果配置open_ basedir =/www/a,那么目录/www/a和/www/ab都是可以访问的。所以如果要将访问仅限制在指定的目录内,请用斜线结束路径名。例如设置成: open_basedir = /www/a/。
Register Globals全局变量注册开关
安全 « PHP Manual | PHP 中文手册 (golaravel.com)
本特性自PHP5.3.0
起废弃并自PHP5.4.0
起移除
在该选项为ON时,会直接把用户通过GET、POST等方式提交上来的参数注册为全局变量,并初始化为参数对应的值。使得提交参数可以直接在脚本中使用
在官方手册中,通过代码示例展示了Register Globals=On
会带来的安全问题,官方示例代码如下
首先是可能带来的越权问题
<?php
// 当用户合法的时候,赋值 $authorized = true
if (authenticated_user()) {
$authorized = true;
}
// 由于并没有事先把 $authorized 初始化为 false,
// 当 register_globals 打开时,可能通过GET auth.php?authorized=1 来定义该变量值
// 所以任何人都可以绕过身份验证
if ($authorized) {
include "/highly/sensitive/data.php";
}
?>
当 register_globals = on 的时候,上面的代码就会有危险了。如果是 off, a u t h o r i z e d 就不能通过如 U R L 请求等方式来改变,这样就好多了,尽管初始化变量是一个良好的编程习惯。比如说,如果在上面的代码执行之前加入 ∗ authorized 就不能通过如 URL 请求等方式来改变,这样就好多了,尽管初始化变量是一个良好的编程习惯。比如说,如果在上面的代码执行之前加入 * authorized就不能通过如URL请求等方式来改变,这样就好多了,尽管初始化变量是一个良好的编程习惯。比如说,如果在上面的代码执行之前加入∗authorized = false* 的话,无论 register_globals 是 on 还是 off 都可以,因为用户状态被初始化为未经认证。
官方的另一个例子如下
<?php
// 我们不知道 $username 的来源,但很清楚 $_SESSION 是
// 来源于会话数据
if (isset($_SESSION['username'])) {
echo "Hello <b>{$_SESSION['username']}</b>";
} else {
echo "Hello <b>Guest</b><br />";
echo "Would you like to login?";
}
?>
当 register_globals = on
的时候,username
会被注册为全局变量,这里攻击者可以通过url中使用Get方式等传递username参数,进行赋值,从而绕过这个简单的验证
同时,官方也给出了应做出的验证–即需要探测有害变量的来源
<?php
if (isset($_COOKIE['MAGIC_COOKIE'])) {
// MAGIC_COOKIE 来自 cookie
// 这样做是确保是来自 cookie 的数据
} elseif (isset($_GET['MAGIC_COOKIE']) || isset($_POST['MAGIC_COOKIE'])) {
mail("admin@example.com", "Possible breakin attempt", $_SERVER['REMOTE_ADDR']);
echo "Security violation, admin has been alerted.";
exit;
} else {
// 这一次请求中并没有设置 MAGIC_COOKIE 变量
}
?>
当然,单纯地关闭 register_globals 并不代表所有的代码都安全了。对于每一段提交上来的数据,都要对其进行具体的检查。永远要验证用户数据和对变量进行初始化!把 error_reporting() 设为
E_NOTICE
级别可以检查未初始化的变量。
allow_url_fopen
安装/配置 « PHP Manual | PHP 中文手册 (golaravel.com)
如果allow_url_fopen为ON,那么php可以读取远程文件进行操作,容易被攻击者利用
默认的封装协议提供用 ftp 和 http 协议来访问远程文件,一些扩展库例如 zlib 可能会注册更多的封装协议。
出于安全性考虑,此选项只能在 php.ini 中设置。
Windows 版在 PHP 4.3.0 之前,以下函数不支持远程文件访问:include,include_once, require,require_once 和GD 和图像处理 函数中的 imagecreatefromXXX 函数。
allow_url_include
安装/配置 « PHP Manual | PHP 中文手册 (golaravel.com)
如果allow_url_include=ON,那么PHP可以包含远程文件。 默认值为Off,从php5.2.0
起可用,php7.4.0开始被废弃
This option allows the use of URL-aware fopen wrappers with the following functions: include, include_once, require, require_once.
涉及的函数有include()
, include_once()
,require()
, require_once()
safe_mode_exec_dir
安全模式 « PHP Manual | PHP 中文手册 (golaravel.com)
如果 PHP 使用了安全模式,system() 和其它程序执行函数将拒绝启动不在此目录中的程序。必须使用 / 作为目录分隔符,包括 Windows 中。
这个选项能控制php可调用的外部命令的目录,如果php程序中有调用外部命令,那么知道外部命令的目录,能控制程序的风险。
如果安全模式打开了,但是却是要执行某些程序的时候,可以指定要执行程序的主目录:
safe_mode_exec_dir = D:/usr/bin
一般情况下是不需要执行什么程序的,所以推荐不要执行系统程序目录。
像那些php的命令执行函数只能在 safe_mode_exec_dir 设置的目录下进行执行操作。
magic_quotes_gpc
php手册解释 安装/配置 « PHP Manual | PHP 中文手册 (golaravel.com)
magic_quotes_gpc
即魔术引号自动过滤
在设置为On的情况下,会自动在GET, POST, COOKIE变量中的单引号,双引号,反斜杠,空字符的前面加上转义字符反斜杠
但在PHP5.4
之后取消了magic_quotes_gpc
magic_quotes_gpc
用于过滤在运行时从客户端提交的数据,这与magic_quotes_runtime
不同
magic_quotes_runtime
php手册解释 安装/配置 « PHP Manual | PHP 中文手册 (golaravel.com)
与magic_quotes_gpc过滤对象一致,并且但在PHP5.4
之后取消了magic_quotes_runtime
需要注意的是,magic_quotes_runtime
只对从数据库或文件中获取的数据进行过滤
magic_quotes_sybase
安装/配置 « PHP Manual | PHP 中文手册 (golaravel.com)
在设置为On的情况下,会覆盖掉magic_quotes_gpc=On
或者magic_quotes_runtime=On
的设置。PHP5.4
之后取消 —本特性已自 PHP 5.3.0 起废弃并将自 PHP 5.4.0 起移除。
与gpc的共同点是处理对象一致,但是magic_quotes_sybase
仅会转义空字符,且把单引号'
修改为两个单引号''
,注意不是双引号,并且addslashes()
和stripslashes()
函数适用
但是,magic_quotes_sybase
转义的前提是magic_quotes_gpc=On
,gpc为off
时是不生效的
If is on, a single-quote is escaped with a single-quote instead of a backslash if magic_quotes_gpc or magic_quotes_runtime are enabled. This setting is also respected by addslashes() and stripslashes().
Note that when is ON it completely overrides . In this case even when is enabled neither double quotes, backslashes or NUL’s will be escaped.
magic_quotes_sybase``magic_quotes_gpc ``magic_quotes_gpc
safe_mode 安全模式
安全模式 « PHP Manual | PHP 中文手册 (golaravel.com)
安全模式是php内嵌的一种安全机制,当配置为On时,可以联动配置指令,详情参考php中文手册
并且配置的范围是PHP_INI_SYSTEM
,自PHP5.4.0
之后取消
当安全模式打开的时候,下列函数的功能将会收到限制-- 所有文件操作函数会收到限制
chdir, move_uploaded_file, chgrp, parse_ini_file, chown, rmdir, copy, rename, fopen, require, highlight_file, show_source, include, symlink, link, touch, mkdir, unlink
同样的,一些php扩展中的函数也将会受到影响。(加载模块:在安全模式下dl函数将被禁止,如果要加载扩展的话,只能修改php.ini
中的扩展选项,在php启动的时候加载)。
在php安全模式打开的时候,需要执行系统程序的时候,必须是在safe_mode_exec_dir选项指定目录的程序,否则执行将失败。即使允许执行,那么也会自动的传递给escapeshellcmd
函数进行过滤。
以下执行命令的函数列表将会受到影响:通过下面函数执行命令或程序会提示错误
exec,shell_exec,passthru,system,popen
另外,背部标记操作符(`)也将被关闭。
当运行在安全模式下,虽然不会引起错误,但是putenv
函数将无效。同样的,其他一些尝试改变php环境变量的函数set_time_limit
, set_include_path
也将被忽略。
disable_functions
php.ini 配置 « PHP Manual | PHP 中文手册 (golaravel.com)
该指令允许用户基于安全原因自定义禁用某些函数。接受逗号分隔的函数名列表作为参数。 disable_functions 不受安全模式的影响。
本指令只能在php.ini
中设置
display_errors
安装/配置 « PHP Manual | PHP 中文手册 (golaravel.com)
显示php脚本内部错误
error_reporting
错误处理 函数 « PHP Manual | PHP 中文手册 (golaravel.com)
用来配置显示错误的级别,其参数为level,可以是一个位掩码也可以是一个已命名的常量。 强烈建议使用已命名的常量,以确保兼容将来的版本。 由于错误级别的添加、整数取值范围的增加, 较久的基于整数的错误级别不会总是和预期的表现一致。
可用的错误级别常量及其实际含义描述在了 predefined constants 中。