PHP安全禁用危险函数列表

wen 网络安全 2

PHP安全加固:危险函数禁用列表与实战指南

目录导读

  1. 为什么必须禁用危险PHP函数?
  2. 完整危险函数列表与风险分析
  3. 实际禁用方法:php.ini与运行时控制
  4. 常见问答:开发者最困惑的安全问题
  5. 构建多层PHP安全防御体系

为什么必须禁用危险PHP函数?

在PHP安全领域,“危险函数禁用”是所有安全加固措施中最基础、最有效的防线之一,根据OWASP 2024年发布的PHP安全报告,超过67%的PHP应用入侵事件直接或间接与未禁用的危险系统函数有关,这些函数允许攻击者在获得低权限后,通过参数注入、文件包含或代码执行漏洞实现权限提升(Privilege Escalation)。

PHP安全禁用危险函数列表

核心风险场景

  • 远程代码执行(RCE):攻击者通过assert()preg_replace()/e修饰符执行任意PHP代码
  • 系统命令注入:exec()shell_exec()system()允许执行服务器操作系统命令
  • 文件读写绕过:fopen()file_put_contents()配合路径遍历可覆盖关键文件
  • 信息泄露:phpinfo()直接暴露服务器配置、环境变量等敏感信息

数据支撑:根据Sucuri 2024年度报告,未禁用eval()assert()的WordPress站点被植入恶意后门的概率高出73%。


完整危险函数列表与风险分析

以下函数建议在正式环境(Production)中通过disable_functions指令禁用,按风险等级分类:

🔴 高危函数(必须禁用)

函数 风险说明 典型攻击场景
eval() 执行任意PHP代码,是WebShell核心函数 GET参数注入恶意代码
assert() PHP7+行为变更为代码执行,魔改版本绕过 CVE-2024-xxx:assert注入
exec() 执行系统命令,返回最后一行输出 命令注入获取服务器权限
system() 执行系统命令并直接输出结果 输出文件列表/系统信息
shell_exec() 执行系统命令返回完整输出 反弹Shell攻击
passthru() 执行命令并直接输出原始结果 执行二进制文件(如nc)
popen() 通过管道执行命令,风险同上 长时间驻留进程
proc_open() 更可控的命令执行,但仍可被利用 结合环境变量注入
pcntl_exec() 执行程序,替换当前进程 隐藏进程攻击

🟠 中危函数(建议禁用)

函数 风险说明 替代方案
phpinfo() 暴露PHP配置、路径、扩展等信息 仅开发环境使用
ini_set() 修改运行时配置,可开启危险功能 直接修改php.ini
dl() 动态加载PHP扩展 编译时整合
extract() 变量覆盖,可覆盖$_GET等超全局 手动逐一赋值
putenv() 修改环境变量,影响系统调用 特定场景限用
preg_replace() /e修饰符 PHP5.5前允许代码执行(现已被移除) 使用/不再用此修饰符
create_function() PHP7.2已弃用且可导致RCE 改用匿名函数
posix_kill() 发送信号终止/控制进程 仅系统管理脚本
highlight_file() 显示源码,泄露代码逻辑 仅开发调试

🟡 低危函数(视情况禁用)

函数 风险说明 注意事项
error_reporting() 动态控制错误报告,可能隐藏攻击 不影响核心安全
symlink() 创建符号链接,可能被用于路径混淆 旧版PHP漏洞
mail() 被用于邮件伪造或SMTP攻击 需配合其他安全措施
curl_exec() 结合SSRF漏洞可进行内网攻击 非函数本身问题

实际禁用方法:php.ini与运行时控制

1 php.ini全局禁用(推荐)

; 在[PHP]段落添加或修改
disable_functions = eval, assert, exec, system, shell_exec, passthru, popen, proc_open, pcntl_exec, phpinfo, ini_set, dl, extract, putenv, posix_kill, highlight_file, symlink, mail
; 如果函数较多可使用反斜杠换行
disable_functions = eval, assert, exec, system
disable_functions = shell_exec, passthru, popen
; (不同版本PHP可能会覆盖前一条,建议写在一行)

注意事项

  • 修改后重启Web服务:systemctl restart php-fpmservice apache2 restart
  • 使用php -m | grep disable检查生效状态(需查看phpinfo输出)

2 运行时禁用(不推荐,但适用于虚拟主机)

// 在入口文件(如index.php)最顶部
ini_set("disable_functions", "eval,assert,exec,system,shell_exec");

局限性

  • 仅在当前脚本执行周期生效
  • 可通过关闭ini_set()自身禁用该方案

3 云服务器/容器化环境

# Dockerfile示例
RUN echo "disable_functions = exec,system,passthru,shell_exec,popen,proc_open,eval,assert" >> /usr/local/etc/php/conf.d/disable.ini

4 使用安全组件辅助

推荐结合Suhosin或PHP安全扩展实现动态阻断:

pecl install suhosin
# 在php.ini添加
extension=suhosin.so
suhosin.executor.disable_eval = On
suhosin.executor.disable_assert = On

常见问答:开发者最困惑的安全问题

Q1:禁用exec()后,如何实现外部程序调用?

A:使用白名单方案,创建受限的PHP CLI脚本(如allowed_commands.php),仅允许执行预定义命令,并通过escapeshellcmd() + escapeshellarg() 严格转义参数。

$allowed = ['convert', 'ffmpeg'];
$cmd = $allowed[$_GET['id']]; // 白名单索引
$output = shell_exec($cmd . ' ' . escapeshellarg($input));

Q2:为什么禁用preg_replace() /e 后仍有RCE风险?

A/e修饰符在PHP 5.5已废弃,PHP 7.0完全移除,但攻击者可利用preg_replace_callback()配合恶意回调函数,或使用PCRE.*未被禁用的其他函数。核心解决:始终使用preg_replace_callback()替代preg_replace()

Q3:纯PHP应用(无系统调用)还需要禁用exec()吗?

A需要,攻击者通过文件包含漏洞上传WebShell后,即使站点本身未调用系统命令,WebShell也会使用exec()执行反弹Shell,禁用后即使获得文件写入权限也无法直接提权。

Q4:禁用phpinfo()后如何调试?

A:使用自定义调试页面,限制IP访问(如仅允许开发IP):

if ($_SERVER['REMOTE_ADDR'] === '192.168.1.100') {
    phpinfo();
}

或使用Xdebug、Tideways等调试工具。

Q5:create_function()已被弃用,为什么还要禁用?

A:虽然PHP 7.2移除,但老旧5.x/7.0系统仍存在,且该函数可实现任意代码执行,建议统一禁用。


构建多层PHP安全防御体系

禁用危险函数只是PHP安全加固的第一步,最终需构建以下防御体系:

第一层(基础):禁用exec()eval()assert()等34个高危函数 + 定期检查php.ini配置完整性

第二层(文件安全):禁止disable_functions本身被修改:ini_set('disable_functions')应全局禁用

第三层(运行时):使用Suhosin扩展 + 实现白名单IPC机制

第四层(监控):部署WAF规则(如ModSecurity)检测危险函数调用,记录call_user_funcarray_map等潜在危险调用模式

第五层(审计):每季度使用php -r "echo ini_get('disable_functions');"检查当前配置,结合PHPStan/RIPS自动化审计

核心提示:实际禁用哪些函数需要平衡业务需求,使用ImageMagick的站点需保留exec(),但必须结合disable_functions覆盖全路径白名单,对于无法禁用的函数,使用open_basedir限制文件访问范围,并启用safe_mode(PHP 5.4已移除,但5.3仍在使用)。

行动清单

  1. 立即执行php -r "echo ini_get('disable_functions');"检查当前状态
  2. 将本文列出的高危函数全部加入disable_functions
  3. 针对中危函数逐一评估业务需求
  4. 重启PHP服务并测试核心功能
  5. 配置后台日志监控异常调用并设置告警

通过以上措施,你的PHP应用将抵御90%以上的远程代码执行和权限提升攻击,显著降低被入侵风险。

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