PHP 怎么PHP 配置审计

wen PHP项目 2

本文目录导读:

PHP 怎么PHP 配置审计

  1. 核心配置文件审计
  2. PHP-FPM配置审计
  3. 自动化审计脚本
  4. 配置加固建议
  5. 常见问题与解决方案

PHP配置审计是Web安全中非常重要的一环,以下是针对PHP配置审计的详细指南,包含关键配置项、安全风险及审计方法。

核心配置文件审计

主要配置文件路径

# 常见位置
/etc/php.ini
/etc/php/7.4/apache2/php.ini
/etc/php/7.4/fpm/php.ini
/usr/local/php/etc/php.ini

关键安全配置项审计清单

; ========== 危险函数禁用 ==========
; 必须禁用的危险函数
disable_functions = exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source,highlight_file,escapeshellarg,escapeshellcmd
; ========== 错误信息控制 ==========
; 生产环境必须关闭
display_errors = Off
display_startup_errors = Off
; 记录错误但不显示
log_errors = On
error_log = /var/log/php_errors.log
; ========== 资源限制 ==========
max_execution_time = 30     ; 最大执行时间
max_input_time = 60         ; 最大输入时间
memory_limit = 128M         ; 内存限制
post_max_size = 8M          ; POST数据限制
upload_max_filesize = 2M    ; 上传文件大小
; ========== 文件操作安全 ==========
allow_url_fopen = Off       ; 禁用远程文件包含
allow_url_include = Off     ; 禁用远程文件包含
open_basedir = /var/www/html:/tmp  ; 限制文件访问范围
; ========== 会话安全 ==========
session.use_strict_mode = 1     ; 严格会话模式
session.use_cookies = 1         ; 使用Cookie
session.use_only_cookies = 1    ; 仅使用Cookie
session.cookie_httponly = 1     ; 禁止JavaScript访问
session.cookie_secure = 1       ; 仅HTTPS传输
session.cookie_samesite = "Lax" ; 防止CSRF
; ========== 全局变量 ==========
register_globals = Off      ; PHP 5.4+已移除
magic_quotes_gpc = Off      ; PHP 5.4+已移除
; ========== 上传安全 ==========
file_uploads = On
upload_tmp_dir = /tmp/php_uploads  ; 必须配置

PHP-FPM配置审计

FPM池配置

; /etc/php/7.4/fpm/pool.d/www.conf
; 以最小权限运行
user = www-data
group = www-data
; 限制PHP进程能打开的连接
listen.allowed_clients = 127.0.0.1
; 进程管理
pm.max_children = 50       ; 最大子进程数
pm.start_servers = 5       ; 启动服务器数
pm.min_spare_servers = 5   ; 最小空闲服务器数
pm.max_spare_servers = 35  ; 最大空闲服务器数
; 请求终止设置
request_terminate_timeout = 60s
request_slowlog_timeout = 5s
slowlog = /var/log/php-slow.log

安全审计脚本示例

<?php
/**
 * PHP配置安全审计脚本
 * 用于检测常见的安全配置问题
 */
class PHPConfigAuditor {
    private $criticalSettings = [];
    private $warnings = [];
    public function checkSecurityConfig() {
        // 1. 危险函数检查
        $dangerousFunctions = ini_get('disable_functions');
        $this->criticalSettings['disable_functions'] = $dangerousFunctions;
        // 2. 错误显示检查
        $this->criticalSettings['display_errors'] = ini_get('display_errors');
        // 3. 远程文件包含检查
        $this->criticalSettings['allow_url_fopen'] = ini_get('allow_url_fopen');
        $this->criticalSettings['allow_url_include'] = ini_get('allow_url_include');
        // 4. 资源限制检查
        $this->criticalSettings['max_execution_time'] = ini_get('max_execution_time');
        $this->criticalSettings['memory_limit'] = ini_get('memory_limit');
        // 5. 文件包含路径限制
        $this->criticalSettings['open_basedir'] = ini_get('open_basedir');
        // 6. 会话安全
        $this->criticalSettings['session.cookie_httponly'] = ini_get('session.cookie_httponly');
        $this->criticalSettings['session.cookie_secure'] = ini_get('session.cookie_secure');
    }
    public function analyze() {
        $issues = [];
        // 分析危险函数
        $safeFunctions = ['exec', 'system', 'passthru', 'shell_exec', 'proc_open'];
        foreach ($safeFunctions as $func) {
            if (strpos($this->criticalSettings['disable_functions'], $func) === false) {
                $issues[] = "⚠️ 危险函数 {$func} 未禁用";
            }
        }
        // 分析错误显示
        if ($this->criticalSettings['display_errors'] !== 'Off' && 
            $this->criticalSettings['display_errors'] !== '0') {
            $issues[] = "❌ display_errors 未关闭 (当前: {$this->criticalSettings['display_errors']})";
        }
        // 分析远程文件包含
        if ($this->criticalSettings['allow_url_fopen'] === 'On' || 
            $this->criticalSettings['allow_url_fopen'] === '1') {
            $issues[] = "❌ allow_url_fopen 处于开启状态";
        }
        // 分析open_basedir
        if (empty($this->criticalSettings['open_basedir'])) {
            $issues[] = "❌ open_basedir 未配置";
        }
        // 分析会话安全
        if ($this->criticalSettings['session.cookie_httponly'] !== '1') {
            $issues[] = "⚠️ session.cookie_httponly 未启用";
        }
        return $issues;
    }
}
// 使用示例
$auditor = new PHPConfigAuditor();
$auditor->checkSecurityConfig();
$issues = $auditor->analyze();
echo "=== PHP 配置安全审计报告 ===\n";
foreach ($issues as $issue) {
    echo $issue . "\n";
}

自动化审计脚本

Shell审计脚本

#!/bin/bash
# php_config_audit.sh
# PHP配置安全审计脚本
PHP_INI="/etc/php/7.4/apache2/php.ini"
echo "=============================="
echo "PHP 配置安全审计报告"
echo "=============================="
# 1. 危险函数检查
echo "\n[1] 危险函数检查:"
for func in "exec" "system" "passthru" "shell_exec" "proc_open"; do
    if grep -q "^disable_functions.*$func" $PHP_INI; then
        echo "✓ $func 已禁用"
    else
        echo "✗ $func 未禁用"
    fi
done
# 2. 错误显示检查
echo "\n[2] 错误显示设置:"
display_errors=$(grep "^display_errors" $PHP_INI | awk '{print $3}')
if [ "$display_errors" = "Off" ]; then
    echo "✓ display_errors 已关闭"
else
    echo "✗ display_errors 未关闭 (当前: $display_errors)"
fi
# 3. 远程文件包含检查
echo "\n[3] 远程文件包含检查:"
allow_url_fopen=$(grep "^allow_url_fopen" $PHP_INI | awk '{print $3}')
if [ "$allow_url_fopen" = "Off" ]; then
    echo "✓ allow_url_fopen 已关闭"
else
    echo "✗ allow_url_fopen 未关闭"
fi
# 4. 文件访问限制
echo "\n[4] 文件访问限制:"
open_basedir=$(grep "^open_basedir" $PHP_INI)
if [ -n "$open_basedir" ]; then
    echo "✓ open_basedir 已配置: $open_basedir"
else
    echo "✗ open_basedir 未配置"
fi
# 5. PHP版本检查
echo "\n[5] PHP版本:"
php_version=$(php -v | head -n 1)
echo "当前版本: $php_version"

Python审计脚本

#!/usr/bin/python3
# php_config_audit.py
import re
def audit_php_config(config_path):
    """审计PHP配置文件"""
    with open(config_path, 'r') as f:
        config_content = f.read()
    # 危险配置正则
    patterns = {
        '危险函数未禁用': r'disable_functions\s*=\s*(?![^;]*(?:exec|system|passthru))',
        '错误显示开启': r'display_errors\s*=\s*On',
        '远程文件包含开启': r'allow_url_fopen\s*=\s*On',
        '文件包含限制未设置': r'(?:^|\n)open_basedir\s*=\s*(?:\n|;)',
        '会话Cookie非HttpOnly': r'session\.cookie_httponly\s*=\s*0',
    }
    issues = []
    for issue_name, pattern in patterns.items():
        if re.search(pattern, config_content, re.MULTILINE):
            issues.append(f"⚠️ {issue_name}")
    return issues
# 使用
issues = audit_php_config('/etc/php/7.4/apache2/php.ini')
for issue in issues:
    print(issue)

配置加固建议

生产环境最小化配置

; 必须关闭
display_errors = Off
display_startup_errors = Off
expose_php = Off
; 必须禁用危险函数
disable_functions = exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source
; 文件包含限制
allow_url_fopen = Off
allow_url_include = Off
open_basedir = /var/www/html:/tmp
; 会话安全
session.use_strict_mode = 1
session.cookie_httponly = 1
session.cookie_secure = 1
session.use_only_cookies = 1

定期审计检查清单

每周/每月自动化审计项目:

  • [ ] 危险函数配置
  • [ ] 错误报告设置
  • [ ] 文件包含配置
  • [ ] 文件访问限制
  • [ ] 会话安全配置
  • [ ] 资源限制配置
  • [ ] PHP版本更新
  • [ ] FPM进程配置

常见问题与解决方案

配置冲突问题

# 查看实际生效配置
php -i | grep "Configuration File"
php -i | grep "Scan this dir for additional .ini files"
# 查看所有加载的配置文件
php --ini

配置变更生效

# Apache
sudo systemctl restart apache2
# Nginx + PHP-FPM
sudo systemctl restart php7.4-fpm
sudo systemctl restart nginx

通过以上审计方法和工具,可以全面检查PHP配置的安全性,建议建立定期的配置审计机制,并关注PHP官方安全公告以获取最新的安全配置建议。

抱歉,评论功能暂时关闭!