Follow-up to #4275, which fixed Uri::ip() reading request variables through getenv() alone. Two more spots in the bootstrap share the same bug class. Neither is security-relevant and neither affects a per-request path, but both fail silently, which is what makes them worth fixing.
1. The GRAV_CONFIG gate disagrees with its own body
system/src/Grav/Common/Processors/InitializeProcessor.php:209
$prefix = 'GRAV_CONFIG';
$env = getenv($prefix); // gate: process environment only
if ($env) {
...
$env = $_ENV + $_SERVER; // body, eleven lines later: reads $_SERVER
The gate and the loop it guards read different sources. Set GRAV_CONFIG with Apache SetEnv or nginx fastcgi_param on a host whose SAPI does not answer getenv(), and the gate is false while every GRAV_CONFIG__* key sits unread in $_SERVER. The entire environment-override feature is skipped with nothing logged.
Confirmed that $_SERVER alone does not satisfy the gate:
$_SERVER['GRAV_CONFIG'] = 'true';
var_dump(getenv('GRAV_CONFIG')); // bool(false)
2. Setup.php reads the GRAV_ENVIRONMENT family through getenv() only
system/src/Grav/Common/Config/Setup.php:185, 207, 240, 243 — GRAV_ENVIRONMENT, GRAV_SETUP_PATH, GRAV_ENVIRONMENT_PATH, GRAV_ENVIRONMENTS_PATH.
Meanwhile system/src/Grav/Common/Config/Env.php:74, 93, 129 already reads the same GRAV_ENVIRONMENT key as $_SERVER[...] ?? $_ENV[...] ?? (getenv(...) ?: null), which is exactly the pattern #4275 introduced. So core already contains the fix, applied inconsistently.
This one is partly mitigated: Env.php deliberately constructs Dotenv with usePutenv(true) because Setup.php reads getenv(), so .env-supplied values work. The gap is only for server-supplied values on a non-answering SAPI.
Suggested fix
Use the Env.php pattern in both places — $_SERVER first, then $_ENV, then getenv() — so a variable set by the server config is honoured however the SAPI exposes it. For the GRAV_CONFIG gate specifically, reading the same $_ENV + $_SERVER array the body already builds would be the smallest change and removes the disagreement entirely.
Follow-up to #4275, which fixed
Uri::ip()reading request variables throughgetenv()alone. Two more spots in the bootstrap share the same bug class. Neither is security-relevant and neither affects a per-request path, but both fail silently, which is what makes them worth fixing.1. The
GRAV_CONFIGgate disagrees with its own bodysystem/src/Grav/Common/Processors/InitializeProcessor.php:209The gate and the loop it guards read different sources. Set
GRAV_CONFIGwith ApacheSetEnvor nginxfastcgi_paramon a host whose SAPI does not answergetenv(), and the gate is false while everyGRAV_CONFIG__*key sits unread in$_SERVER. The entire environment-override feature is skipped with nothing logged.Confirmed that
$_SERVERalone does not satisfy the gate:2.
Setup.phpreads theGRAV_ENVIRONMENTfamily throughgetenv()onlysystem/src/Grav/Common/Config/Setup.php:185, 207, 240, 243—GRAV_ENVIRONMENT,GRAV_SETUP_PATH,GRAV_ENVIRONMENT_PATH,GRAV_ENVIRONMENTS_PATH.Meanwhile
system/src/Grav/Common/Config/Env.php:74, 93, 129already reads the sameGRAV_ENVIRONMENTkey as$_SERVER[...] ?? $_ENV[...] ?? (getenv(...) ?: null), which is exactly the pattern #4275 introduced. So core already contains the fix, applied inconsistently.This one is partly mitigated:
Env.phpdeliberately constructs Dotenv withusePutenv(true)becauseSetup.phpreadsgetenv(), so.env-supplied values work. The gap is only for server-supplied values on a non-answering SAPI.Suggested fix
Use the
Env.phppattern in both places —$_SERVERfirst, then$_ENV, thengetenv()— so a variable set by the server config is honoured however the SAPI exposes it. For theGRAV_CONFIGgate specifically, reading the same$_ENV + $_SERVERarray the body already builds would be the smallest change and removes the disagreement entirely.