必须同时隐藏PHP版本号和禁用危险函数:设expose_php=Off关闭X-Powered-By头;禁用19个高危函数并用php_admin_value在FPM Pool层强制锁定,最后CLI与Web双端验证生效。

隐藏PHP版本号和禁用危险函数,是PHP环境上线前必须完成的两项基础安全动作。单独做其中一项效果有限——攻击者看到 X-Powered-By: PHP/8.5.5 就能针对性构造漏洞利用;而只禁函数却不隐藏版本,等于主动暴露技术栈细节,增加被精准打击的风险。
一、隐藏PHP版本信息(expose_php)
默认情况下,PHP会在HTTP响应头中输出版本号,例如 X-Powered-By: PHP/8.5.5。这为攻击者提供了直接情报,应立即关闭。
- 打开 php.ini,找到
expose_php配置项,将其设为 Off:expose_php = Off - 该设置无需重启Web服务器,但需确保配置已加载——可访问
phpinfo()页面,搜索 “expose_php”,确认值为 Off - 若使用 Nginx + PHP-FPM,还需检查是否在 fastcgi_params 中手动添加了
fastcgi_param SERVER_SOFTWARE "nginx";类覆盖项,避免前端透出其他标识
二、禁用危险函数(disable_functions)
禁用不是“越多越好”,而是聚焦仍具执行能力、易被Webshell利用的函数。PHP 8.5 环境下,以下19个函数构成当前最精简有效的封锁面:
-
exec,passthru,shell_exec,system,proc_open,popen,pcntl_exec—— 直接调用系统命令 -
eval,assert,dl,create_function—— 动态代码执行(create_function在 7.2+ 已废弃,但部分旧扩展仍支持,建议保留) -
symlink,link,chown,chgrp,chmod,parse_ini_file,curl_exec,curl_multi_exec,show_source,file_put_contents—— 支持写入、提权、读取敏感文件或辅助RCE落地
配置时务必注意:
– 函数名全部小写,无空格,无换行,英文逗号分隔
– 不要写成 exec, system(带空格会失效)
– 修改后必须重启 PHP-FPM 进程(如 systemctl restart php85-fpm),仅 reload Web服务器无效
立即学习“PHP免费学习笔记(深入)”;
三、强制生效:FPM Pool 层二次覆盖
php.ini 的 disable_functions 可被运行时函数(如 ini_set())绕过。生产环境必须在 FPM Pool 配置中用 php_admin_value 强制锁定:
- 编辑
/etc/php/8.5/fpm/pool.d/www.conf(路径依版本调整) - 在
[www]段内添加:php_admin_value[disable_functions] = exec,passthru,shell_exec,system,proc_open,popen,pcntl_exec,eval,assert,dl,parse_ini_file,curl_exec,curl_multi_exec,show_source,file_put_contents,symlink,chmod,chown,chgrp - 执行
systemctl reload php85-fpm即可生效,无需完全重启
四、验证是否真正生效
不能只看配置文件写了什么,必须实测:
-
CLI 验证:
/usr/bin/php8.5 -r "var_dump(system('id'));"应报错:Warning: system() has been disabled... -
Web 验证:新建
test.php,内容为<?php echo @system('id'); ?>,访问后页面应为空或报错 -
双端一致性检查:
php -i | grep disable_functions和phpinfo()页面中对应字段必须一致
这两步做完,就切断了绝大多数自动化攻击工具的第一波探测与执行路径。不复杂,但容易忽略细节。



















