网站漏洞防护的核心手段之一,就是在PHP运行环境中禁用"eval"函数并配置危险函数黑名单。"eval"函数能将字符串当作PHP代码执行,一旦被攻击者利用上传的恶意脚本调用,服务器就等于把执行权限完全交给了对方。具体做法是打开php.ini配置文件,找到"disable_functions"指令,将"eval"以及"system"、"exec"、"shell_exec"、"passthru"、"popen"、"proc_open"、"putenv"、"dl"等高危函数全部列入禁用列表。这不是可选项,而是任何生产环境PHP服务器的必做项。
很多站长觉得自己网站用的是成熟CMS就不需要管这些,实际上恰恰相反。WordPress、ThinkPHP、DedeCMS等主流系统的历史漏洞中,大量远程代码执行(RCE)攻击链都依赖"eval"或类似动态执行函数来完成提权。禁用这些函数不会影响正常业务逻辑,但能直接切断攻击者最常用的后门植入通道。
一、为什么必须禁用PHP eval函数"eval"是PHP中最危险的函数,没有之一。它的作用是把一个字符串当作PHP代码来解析和执行。正常开发中几乎不需要用到它,但攻击者一旦找到文件上传漏洞或者模板注入点,就会构造类似这样的payload:
eval($_POST['cmd']);
只要这一行代码被写入到可访问的PHP文件中,攻击者就能通过POST请求执行任意系统命令。更隐蔽的写法是利用编码绕过,比如base64编码后再eval解码执行,或者用"assert"函数(本质也是eval)来绕过简单的关键词过滤。所以单纯靠WAF规则拦截关键词是不够的,必须从PHP运行层面彻底禁用。
从安全合规角度看,等保2.0三级以上要求对服务器进行安全加固,禁用危险函数是明确的检查项。PCI DSS标准同样要求最小化PHP可用函数集。不做这一步,等保测评直接不通过。
二、PHP危险函数完整黑名单及分类危险函数不只是"eval"一个,需要系统性地梳理。按照危害程度可以分为以下几类:
第一类:代码执行类
这类函数能直接执行系统命令或PHP代码,危害最高:
eval, assert, system, exec, shell_exec, passthru, popen, proc_open, pcntl_exec
第二类:文件操作类
攻击者利用这些函数读取敏感文件、写入后门、修改配置:
file_get_contents, file_put_contents, fwrite, fread, fopen, unlink, rename, copy, move_uploaded_file, chmod, chown, touch, mkdir, rmdir, symlink, link, dl
第三类:信息泄露类
这些函数会暴露服务器内部信息,帮助攻击者进一步渗透:
phpinfo, get_current_user, getmyuid, getmypid, getenv, ini_get, ini_set, error_reporting, highlight_file, show_source, print_r, var_dump, debug_backtrace, debug_print_backtrace
第四类:网络与进程类
允许对外发起连接或操控进程:
fsockopen, curl_exec, curl_multi_exec, stream_socket_client, stream_socket_server, socket_create, socket_bind, socket_listen, socket_accept, putenv, pcntl_fork, pcntl_alarm
需要注意的是,并不是所有这些函数都要一刀切禁用。比如"file_get_contents"和"fopen"在正常业务中大量使用,禁用会导致网站无法运行。正确的做法是根据业务需求分级禁用,只禁用那些业务绝对用不到的高危函数。
三、具体配置方法:php.ini修改步骤修改"disable_functions"是最直接有效的方式。操作步骤如下:
第一步,找到php.ini文件位置。不同环境路径不同:
Linux系统通常在:/etc/php/8.1/fpm/php.ini 或 /etc/php.ini 宝塔面板:/www/server/php/81/etc/php.ini Windows系统:C:\php\php.ini
第二步,打开文件搜索"disable_functions",如果没有就手动添加一行:
disable_functions = eval,system,exec,shell_exec,passthru,popen,proc_open,putenv,dl,assert,pcntl_exec,pcntl_fork
第三步,保存文件后重启PHP服务使配置生效:
systemctl restart php-fpm # 或者 service php8.1-fpm restart
第四步,验证是否生效。创建一个test.php文件:
<?php phpinfo(); ?>
在页面中搜索"disable_functions",确认目标函数已被禁用。也可以用命令行验证:
php -i | grep disable_functions四、宝塔面板和虚拟主机环境的特殊处理
如果你用的是宝塔面板,可以在面板后台直接操作:进入"软件商店"→"PHP设置"→选择对应版本→"禁用函数",在文本框中填入函数名,用逗号分隔即可。宝塔会自动写入对应的php.ini文件。
对于虚拟主机用户,如果没有权限修改php.ini,可以在网站根目录创建一个"user.ini"文件(部分PHP版本支持),或者在".htaccess"中添加:
php_value disable_functions "eval,system,exec,shell_exec"
但需要注意,".htaccess"方式只在PHP以Apache模块模式运行时有效,如果是PHP-FPM模式则不生效。虚拟主机用户最稳妥的方式是联系主机商,要求在服务器层面配置。
五、仅禁用函数还不够:纵深防御策略禁用危险函数只是第一层防护,真正的安全需要多层叠加。以下是必须同步做的事情:
1. 关闭PHP错误显示
生产环境必须关闭错误回显,否则攻击者可以通过报错信息获取路径和数据库信息:
display_errors = Off log_errors = On error_log = /var/log/php/error.log error_reporting = E_ALL
2. 限制文件上传类型和目录
即使禁用了eval,如果攻击者能上传PHP文件到Web目录,仍然可以通过其他方式执行。所以要:限制上传扩展名为白名单、上传目录禁止执行PHP、重命名上传文件、使用随机文件名。
3. 使用open_basedir限制文件访问范围
在php.ini中配置:
open_basedir = /www/wwwroot/your_site/:/tmp/
这样PHP脚本只能访问指定目录内的文件,无法读取/etc/passwd等系统文件。
4. 部署Web应用防火墙(WAF)
WAF可以在HTTP层拦截恶意请求,配合PHP层面的函数禁用形成双重防护。常见的开源方案有ModSecurity、宝塔自带防火墙、云盾等。
5. 定期更新PHP版本和依赖组件
PHP 5.x早已停止安全维护,PHP 7.4也已EOL。务必使用PHP 8.1或8.2以上版本,新版本本身就移除或弱化了部分危险函数,安全基线更高。
六、禁用函数后常见兼容性问题及解决方案禁用某些函数后,部分程序可能报错。常见情况和处理方式:
问题一:WordPress后台提示某些功能不可用
WordPress的某些插件会用到"exec"或"system"来执行定时任务。解决方案是使用WP-Cron替代系统cron,或者单独为该站点开放特定函数(通过不同的php.ini或FastCGI配置)。
问题二:图片处理库报错
GD库和ImageMagick的某些操作需要"exec"调用外部命令。可以改用纯PHP实现的图片处理方案,或者在隔离环境中单独允许。
问题三:Composer安装依赖失败
Composer本身不依赖这些危险函数,但某些post-install脚本可能会调用。检查composer.json中的scripts段,移除不必要的系统调用。
核心原则是:业务需要的函数保留,不需要的一律禁用。不要因为怕麻烦就全部放开,那等于没做防护。
七、自动化检测与持续监控配置完成后,建议建立定期检查机制。可以写一个简单的监控脚本,每周检测一次disable_functions配置是否被篡改:
<?php
$ini = php_ini_loaded_file();
$content = file_get_contents($ini);
if (strpos($content, 'eval') !== false) {
// 发送告警邮件
mail('admin@yoursite.com', '安全告警', 'php.ini中eval未被禁用');
}
?>
同时结合文件完整性监控工具(如AIDE、OSSEC),检测Web目录下是否出现了可疑的PHP文件。任何非预期的新增PHP文件都应该触发告警。
八、总结与行动建议PHP危险函数禁用是网站安全加固中投入产出比最高的操作之一。它不需要花钱、不需要复杂技术、不影响正常业务,却能直接封堵最常见的攻击路径。具体行动清单:立即检查当前php.ini中的disable_functions配置,补全缺失的高危函数;确认open_basedir和错误显示已正确设置;评估业务兼容性并做针对性调整;建立定期巡检机制。安全不是一次性工作,而是持续运营的过程。把基础防护做扎实,才能在面对真正的攻击时有底气。
