php / php/php-src

Unexpected clearing of $_SERVER superglobal when accessing $_ENV in PHP-FPM

未关闭
#15,428 1 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

Bug SAPI: fpm Status: Needs Triage
主要语言
C
星标
40.4k
派生
8.2k
平均合并
2 天 13 小时
30 天内合并 PR
96

描述

Description

Summary:
When using PHP-FPM, accessing the $_ENV superglobal with filter_var() or directly can cause the $_SERVER superglobal to lose its values, specifically REMOTE_ADDR, which unexpectedly becomes null. Notably, this occurs even if the code accessing $_ENV is placed after an exit, which should prevent it from executing. This behavior does not occur when using PHP with other SAPIs, such as Apache’s mod_php.

Steps to Reproduce:

  1. Create a PHP script with the following content:
<?php

$remoteAddr = filter_input(INPUT_SERVER, 'REMOTE_ADDR', FILTER_VALIDATE_IP);

if ($remoteAddr === null) {
    echo 'REMOTE_ADDR is not set';
} elseif ($remoteAddr === false) {
    echo 'Invalid IP address';
} else {
    echo "IP Address: $remoteAddr";
}

exit;

// Accessing $_ENV with filter_var, which should not execute due to the exit above
$appEnv = filter_var($_ENV['APP_ENV'], FILTER_SANITIZE_SPECIAL_CHARS);
  1. Run this script using PHP-FPM with either Nginx or Apache as the reverse proxy.

  2. Expected Behavior: The script should display the client’s IP address from $_SERVER['REMOTE_ADDR'] and then terminate execution after the exit statement, meaning the code below exit should never be executed or have any effect.

  3. Actual Behavior: The script displays "REMOTE_ADDR is not set", indicating that $_SERVER['REMOTE_ADDR'] is unexpectedly null, despite the exit command being in place. This suggests that simply having the filter_var($_ENV['APP_ENV']... line in the script is enough to cause this behaviour, even though the line should never actually run due to the exit.

  4. Modify the script to use filter_input for $_ENV:

$appEnv = filter_input(INPUT_ENV, 'APP_ENV', FILTER_SANITIZE_SPECIAL_CHARS);
  1. Observed Behaviour: When filter_input is used instead of directly accessing $_ENV, the issue does not occur, and $_SERVER['REMOTE_ADDR'] is correctly set, even though this line should not execute due to the preceding exit.

Question:
Is this behavior expected when using PHP-FPM, or is it a quirk that should be addressed? The fact that this occurs even with the exit command in place suggests there might be an underlying issue in how PHP-FPM manages superglobals. If it’s expected, could it be documented more clearly to avoid confusion for developers relying on superglobals like $_SERVER and $_ENV?

PHP Version

PHP 8.3.10, observed down to PHP 5.6.40

Operating System

No response

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

首先,使用所述的脚本和版本通过 PHP-FPM 重现该行为,然后将其与另一个 SAPI(例如 Apache mod_php)进行比较。追踪 filter_var() 或直接访问 $_ENV 与 $_SERVER 和 REMOTE_ADDR 的关系,并检查现有的 FPM 和超全局变量测试。完成的标准是解释清楚该行为并将其修正或记录下来,同时覆盖退出情况。

由索引模型根据 Issue 内容生成。

评估

技术栈
c, php
领域
backend
Issue 类型
缺陷
难度
4/5
预计耗时
3-5 天
活跃度
停滞
描述清晰度
基本清楚
新手友好度
32/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。