php / php/php-src

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

Open
#15,428 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Bug SAPI: fpm Status: Needs Triage
Dominant language
C
Stars
40.4k
Forks
8.1k
Avg merge
2d 13h
Merged PRs (30d)
96

Description

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

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the behavior with PHP-FPM using the script and versions described, then compare it with another SAPI such as Apache mod_php. Trace how filter_var() or direct $_ENV access relates to $_SERVER and REMOTE_ADDR, and check the existing FPM and superglobal tests. Done means the behavior is explained and corrected or documented, with coverage for the exit case.

Written by the indexing model from the issue text.

Assessment

Tech stack
c, php
Domain
backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
32/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.