PHP配置文件php.ini是服务器安全的第一道防线,但很多开发者只关注性能而忽略安全配置。据Verizon《数据泄露调查报告》显示,约30%的Web应用漏洞与配置错误直接相关。php.ini安全配置不当会导致服务器被远程执行代码、信息泄露、文件包含等严重威胁。以下五个危险选项必须立即禁用,否则你的PHP应用就像开着门欢迎攻击者。
display_errors在生产环境必须关闭,因为它会将错误信息直接输出到浏览器,暴露数据库凭据、文件路径、甚至SQL语句等敏感数据。正确做法是:
display_errors = Off log_errors = On error_log = /var/log/php_errors.log
这样可以确保错误记录到日志文件而非输出给用户。对比一下开启和关闭的后果:
| 配置 | 风险 | 建议 |
|---|---|---|
| display_errors = On | 攻击者可通过错误信息获取系统路径、数据库结构等 | 生产环境必须关闭 |
| display_errors = Off | 错误信息只记录日志,不暴露给用户 | 配合log_errors使用 |
我曾见过一个案例,某电商网站因为开启了display_errors,导致数据库密码在错误页面中明文显示,最终被攻击者拖库。这个教训值得所有开发者警惕。
allow_url_fopen和allow_url_include同时开启是远程文件包含攻击的根源,必须关闭。allow_url_fopen允许PHP通过fopen等函数打开远程文件,allow_url_include则允许include/require远程文件。这两个选项同时开启相当于允许攻击者从远程服务器加载恶意脚本。据SANS研究所统计,远程文件包含漏洞在Web应用漏洞中占比约12%。
安全配置:
allow_url_fopen = Off allow_url_include = Off
如果业务确实需要获取远程内容,建议使用更安全的cURL库并严格验证输入。对比表格:
| 配置状态 | 攻击面 | 安全等级 |
|---|---|---|
| 两者都开启 | 极高,可远程包含任意文件 | 危险 |
| 仅allow_url_fopen开启 | 中等,可远程读取文件 | 需谨慎 |
| 两者都关闭 | 低,无法使用远程文件操作 | 安全 |
很多开发框架在安装时要求开启allow_url_fopen,但这不是必须的。建议关闭后通过其他方式解决依赖。
disable_functions必须包含exec、system等危险函数,否则攻击者获得代码执行权限后可直接执行系统命令。PHP提供了大量系统级函数,如exec, system, passthru, shell_exec, popen, proc_open等。据CVE数据库统计,涉及PHP命令执行的高危漏洞中,超过60%利用了未被禁用的危险函数。
推荐配置:
disable_functions = exec,system,passthru,shell_exec,popen,proc_open,dl,phpinfo,assert,pcntl_exec,proc_get_status,putenv,ini_set,set_time_limit,set_include_path,highlight_file,show_source,file_get_contents
注意:不要禁用phpinfo(),因为它用于调试,但生产环境应通过Web服务器配置禁止访问phpinfo页面。但为了安全,可以在disable_functions中加入phpinfo。实际业务中,如果不需要执行外部命令,尽量禁用所有exec系列函数。
open_basedir必须设置为仅允许访问项目目录,否则PHP脚本可以读取服务器任意文件。如果不设置,PHP脚本可以读取服务器上的任何文件,如/etc/passwd、日志文件、其他站点的配置等。设置open_basedir可以极大地缩小攻击面。
配置示例:
open_basedir = "/var/www/html:/tmp"
注意:需要包含/tmp目录,因为一些临时文件操作需要。另外,多个目录用冒号分隔(Windows下用分号)。如果使用PHP-FPM,可以在pool配置中单独设置每个站点的open_basedir,实现虚拟主机隔离。
对比:
| 配置 | 风险 | 建议 |
|---|---|---|
| 未设置open_basedir | PHP可读取任意文件,如/etc/passwd、数据库配置文件 | 必须设置 |
| 设置了open_basedir | 只能访问指定目录,增加安全性 | 目录越精确越好 |
实际渗透测试中,很多攻击者通过读取../config.php来获取数据库密码,如果设置了open_basedir,这种攻击就无效了。
expose_php必须关闭,因为它会在HTTP响应头中暴露PHP版本,帮助攻击者定位已知漏洞。expose_php指令决定是否在HTTP响应头中加入X-Powered-By: PHP/x.x.x字段。这个信息告诉攻击者服务器的PHP版本,攻击者可以针对已知漏洞进行攻击。虽然这不是直接的安全漏洞,但减少了攻击者收集信息的难度。
配置:
expose_php = Off关闭后,响应头中不会出现PHP版本信息。同时,建议修改Server tokens隐藏Web服务器版本。据安全专家建议,信息隐藏是纵深防御的起点。
以上五个php.ini安全配置选项是安全加固中最基础也最容易被忽视的环节。除了这些,还需要注意session安全、文件上传限制、内存限制等。但优先级最高的是立即关闭这五个危险选项。定期审计php.ini配置文件,使用自动化工具(如Lynis或PHP Security Scanner)进行检查,可以持续保持安全基线。
评论
加载中...