一、问题/场景描述
在PHP应用部署或安全加固过程中,开发者常面临一个关键问题:如何防止恶意用户利用PHP内置的某些危险函数执行系统命令、读取敏感文件或进行其他破坏性操作。这些函数如果被不当调用,会严重威胁服务器安全,导致数据泄露甚至系统被完全控制。
二、原因分析
PHP为了提供强大的系统交互和文件操作能力,内置了如 system、exec、shell_exec、passthru 等函数,它们可以直接调用操作系统命令。此外,eval 函数可以动态执行任意PHP代码,phpinfo 可能泄露服务器配置信息。在共享主机环境或代码存在安全漏洞(如命令注入、代码注入)时,攻击者可能利用这些函数获取服务器权限。因此,在非必要的情况下,在 php.ini 配置文件中禁用这些高危函数是至关重要的安全实践。
三、详细解决步骤
通过修改PHP的配置文件 php.ini 中的 disable_functions 指令,可以禁止指定的函数在PHP脚本中被调用。以下是详细的操作步骤。
步骤1:定位php.ini文件
首先,需要找到当前PHP环境正在使用的 php.ini 配置文件的位置。可以通过创建一个包含 phpinfo() 函数的PHP页面来查找,或者直接在命令行中执行以下命令:
php --ini | grep "Loaded Configuration File"
命令输出会显示类似 /usr/local/php/etc/php.ini 的路径,这就是你需要编辑的主配置文件。
步骤2:编辑php.ini配置文件
使用文本编辑器(如vim或nano)以管理员权限打开找到的 php.ini 文件。
sudo vim /usr/local/php/etc/php.ini
在文件中搜索 disable_functions 指令。如果该行以分号 ; 开头,则表示该指令被注释,需要先删除分号以启用它。
步骤3:配置要禁用的函数列表
在 disable_functions 指令后,等号右边用逗号分隔列出所有需要禁用的函数名。建议禁用的常见危险函数列表如下:
disable_functions = system, exec, shell_exec, passthru, proc_open, popen, eval, assert, phpinfo, show_source, highlight_file, dl, symlink, chmod, chown
你可以根据实际业务需求调整此列表。例如,如果应用确实需要执行系统命令(如某些运维脚本),则不应禁用 exec 等函数,但必须确保调用这些函数的代码是绝对安全的。
步骤4:保存并重启PHP服务
保存对 php.ini 文件的修改。修改完成后,必须重启PHP-FPM服务或Web服务器(如Apache、Nginx)才能使新配置生效。
对于使用PHP-FPM的情况(常见于Nginx):
sudo systemctl restart php-fpm
对于Apache模块模式:
sudo systemctl restart apache2
步骤5:验证配置是否生效
创建一个测试PHP文件(例如 test_disable.php),内容为尝试调用已被禁用的函数。
<?php
echo "Testing disabled functions:
";
@system('whoami');
@exec('ls -la');
echo "If you see no command output above, the functions are successfully disabled.";
?>
在浏览器中访问此文件。如果配置生效,页面将不会输出任何命令执行的结果,并且可能不会报错(取决于错误报告设置),或者显示函数被禁用的警告。这表明危险函数已被成功禁用。
四、注意事项
禁用函数前务必评估应用依赖,避免禁用业务必需函数导致功能异常。此配置对CLI命令行模式通常无效,仅影响通过Web服务器执行的PHP脚本。修改配置后必须重启服务。禁用 eval 和 assert 可能影响某些依赖动态代码执行的旧框架或代码,需谨慎处理。
五、适用环境
适用于所有使用PHP作为后端语言,且需要通过配置提升服务器安全性的Web应用部署环境。
