一、PHP默认配置的安全隐患

很多PHP开发者可能没意识到,安装完PHP后的默认配置其实藏着不少安全漏洞。这就好比买了新房子不换锁,总觉得开发商配的锁肯定安全,实际上可能一捅就开。

举个例子,PHP默认开启的register_globals功能(虽然现在新版已经废弃,但很多老系统还在用):

// 当register_globals=On时
// 用户访问 http://example.com/?admin=1 
// 会直接生成$admin变量并赋值为1
if ($admin) {
    // 用户无需认证就能进入管理后台
}

另一个常见问题是allow_url_include

// 如果allow_url_include=On
include($_GET['file']); 
// 攻击者可以传入http://恶意网站/shell.txt执行远程代码

二、必须修改的核心配置项

1. 关闭危险函数

在php.ini中找到disable_functions配置:

; 禁用危险函数(技术栈:PHP 8.x)
disable_functions = 
    exec,passthru,shell_exec,system,
    proc_open,popen,parse_ini_file,
    show_source,highlight_file,
    symlink,link

2. 文件上传限制

; 限制上传功能(技术栈:PHP 7.4+)
file_uploads = On       ; 保持开启但严格限制
upload_max_filesize = 2M
max_file_uploads = 3    
post_max_size = 8M      ; 必须大于upload_max_filesize

3. 错误信息泄露防护

; 生产环境必须设置(技术栈:PHP 5.6+)
display_errors = Off       
log_errors = On
error_log = /var/log/php_errors.log

三、会话安全加固方案

PHP的会话机制默认也有安全隐患,需要特别处理:

1. 会话固定防护

// 每次登录生成新会话ID(技术栈:PHP 7.0+)
session_start();
session_regenerate_id(true); 

// 同时设置cookie属性
setcookie(
    session_name(),
    session_id(),
    [
        'path' => '/',
        'secure' => true,    // 仅HTTPS
        'httponly' => true,  // 禁止JS访问
        'samesite' => 'Strict'
    ]
);

2. 会话超时设置

; php.ini配置(技术栈:PHP 5.4+)
session.gc_maxlifetime = 1800  ; 30分钟
session.cookie_lifetime = 0    ; 浏览器关闭失效

四、数据库连接安全实践

1. 使用预处理语句

// 正确做法(技术栈:PDO + MySQL)
$pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass', [
    PDO::ATTR_EMULATE_PREPARES => false,  // 禁用模拟预处理
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
]);

$stmt = $pdo->prepare("SELECT * FROM users WHERE email = :email");
$stmt->execute(['email' => $_POST['email']]);

2. 连接加密配置

; mysqli加密连接(技术栈:PHP 7.3+)
mysqli.allow_local_infile = Off
mysqli.allow_persistent = Off
mysqli.ssl_verify_server_cert = On

五、实战:安全配置检查脚本

这里提供一个自动检查PHP配置的脚本:

/**
 * PHP安全配置检查工具
 * 技术栈:PHP 5.6+
 */
function check_php_security() {
    $report = [];
    
    // 检查危险配置
    $dangerous = [
        'register_globals' => 'Off',
        'allow_url_include' => 'Off',
        'expose_php' => 'Off'
    ];
    
    foreach ($dangerous as $key => $expected) {
        $current = ini_get($key);
        $report[$key] = [
            'current' => $current,
            'safe' => ($current == $expected)
        ];
    }
    
    // 检查已禁用函数
    $disabled = explode(',', ini_get('disable_functions'));
    $required_disable = ['exec', 'system', 'passthru'];
    foreach ($required_disable as $func) {
        $report['disabled_'.$func] = in_array($func, $disabled);
    }
    
    return $report;
}

// 执行检查
print_r(check_php_security());

六、关联技术:Web服务器加固

Nginx配套配置示例

server {
    # 禁止访问敏感文件
    location ~* \.(env|log|htaccess)$ {
        deny all;
    }
    
    # 限制PHP文件直接访问
    location ~* \.php$ {
        if ($uri !~ "^/index.php") {
            return 403;
        }
        fastcgi_pass 127.0.0.1:9000;
        # ...其他fastcgi参数
    }
}

七、应用场景分析

  1. 电商系统:需要特别注意文件上传和数据库安全配置
  2. CMS系统:要防范包含漏洞和XSS攻击
  3. API服务:应关闭所有错误显示并严格限制HTTP方法

八、技术优缺点对比

安全措施 优点 缺点
禁用危险函数 直接阻断攻击途径 可能影响老旧系统运行
严格上传限制 防止webshell上传 需要根据业务调整大小
关闭错误显示 避免信息泄露 增加调试难度

九、注意事项

  1. 修改配置前一定要备份php.ini文件
  2. 生产环境和开发环境需要不同配置
  3. 每次PHP版本升级后要重新检查配置
  4. 使用opcache时要特别注意其安全配置

十、总结建议

PHP的安全配置就像给系统穿上防弹衣,虽然不能保证100%安全,但能抵挡大部分常见攻击。建议按照以下优先级处理:

  1. 立即关闭register_globals等危险配置
  2. 然后处理文件上传和错误显示
  3. 最后细化会话和数据库安全

定期使用安全脚本检查配置,保持对PHP安全公告的关注,这样才能构建真正安全的PHP应用环境。