allow_url_include 和 allow_url_fopen 必须设为 Off,前者可直接导致 RCE,后者降低 SSRF 风险;需禁用危险流包装器、限制 include_path、配置 open_basedir 并严格核对各层级实际生效值。
php.ini 中 allow_url_include 和 allow_url_fopen 必须关掉
这两个配置项是 lfi 升级为远程代码执行(rce)的关键跳板。只要 allow_url_include 开着,攻击者就能用 php://input、data:// 或 expect:// 协议直接执行任意代码,根本不需要文件上传或写权限。
实操建议:
-
allow_url_include = Off—— 这条必须设为Off,没有例外场景;On状态下,哪怕include()参数做了白名单过滤,也可能被绕过 -
allow_url_fopen = Off—— 虽然不直接导致 RCE,但会禁用file_get_contents("http://...")类行为,减少 SSRF 和二次包含风险 - 修改后必须重启 PHP 服务(如
systemctl restart php-fpm或apachectl graceful),仅 reload 不生效 - 检查是否被 .htaccess 或 user.ini 覆盖:在 Web 目录放一个
info.php,内容为<?php phpinfo(); ?>,搜索这两项的实际值
禁用危险的伪协议和流包装器
PHP 默认启用一堆能读取/执行内容的流,比如 php://filter 可用来泄露源码(Base64 编码绕过 ?> 截断),phar:// 在反序列化场景中可触发任意类加载。
实操建议:
- 在
php.ini中设置disable_functions = system,exec,passthru,shell_exec,proc_open,popene,parse_ini_file,show_source,highlight_file—— 注意不要漏掉parse_ini_file,它常被用于读取配置泄露 - 用
stream_wrapper_unregister("phar")在启动脚本中注销phar流(PHP 7.4+ 支持),比单纯依赖disable_functions更彻底 - 避免在生产环境启用
extension=expect.so—— 这个扩展一旦存在,expect://就能直接执行 shell 命令,且无法通过disable_functions屏蔽
限制 include_path 和默认工作目录
当开发者用相对路径包含文件(如 include "$lang.".php),而 include_path 设置过宽(比如含 . 或 /tmp),攻击者可能通过目录遍历把恶意文件拖进包含链。
实操建议:
-
include_path = "/var/www/app/includes"—— 明确指定唯一可信路径,去掉.和/tmp等高危位置 - 在入口脚本开头加
chdir("/var/www/app"),再配合open_basedir = /var/www/app:/tmp(注意:/tmp 仅保留必要日志写入,不含可执行逻辑) - 如果用了 Composer 自动加载,确认
vendor/autoload.php不在 Web 可访问路径下;否则?f=vendor/autoload.php可能直接暴露 autoloader 行为,辅助路径猜测
用 open_basedir 划清文件操作边界
这个配置不是万能,但它能硬性阻止 PHP 脚本访问指定目录之外的任何文件 —— 包括 include、file_get_contents、fopen 等所有文件 I/O 操作。
实操建议:
-
open_basedir = /var/www/app:/tmp—— 多路径用冒号分隔(Linux)或分号(Windows),不能留空或设为/ - 若应用需访问多个独立目录(如上传目录、模板目录、日志目录),全部列出来,别图省事只写父目录
- Apache 用户注意:
open_basedir在虚拟主机配置里用php_admin_value open_basedir设置才不可被 .htaccess 覆盖;Nginx + PHP-FPM 则需在 pool 配置里加php_admin_value[open_basedir] - 开启后,
getcwd()返回值受限制,某些依赖当前路径的旧代码会报Warning: getcwd(): open_basedir restriction in effect,得改用绝对路径
最麻烦的不是配错哪一项,而是不同层级配置互相覆盖 —— php.ini、pool 配置、.htaccess、user.ini、ini_set() 都可能干预同一参数。上线前务必用 php -i | grep -E "(allow_url|open_basedir|disable_functions)" 和 Web 端 phpinfo() 双向核对实际生效值。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










