
Questa vulnerabilità è basata sulla vulnerabilità CVE-2024-50340
L'opzione register_argc_argv deve essere abilitata nel file di configurazione PHP (php.ini). Questa impostazione carica gli argomenti della riga di comando e i parametri di query in $_SERVER['argv'].
https://www.php.net/manual/en/ini.core.php#ini.register-argc-argv
//Illuminate\Foundation\Application
public function detectEnvironment (Closure $callback)
{
$args = $_SERVER['argv'] ?? null;
return $this['env'] = (new EnvironmentDetector)->detect($callback, $args);
}
Scopo: questo metodo rileva l'ambiente accedendo a $_SERVER['argv'], che contiene gli argomenti della riga di comando, e poi delega alla classe EnvironmentDetector.
Sorgente della vulnerabilità: basandosi su $_SERVER['argv'], qualsiasi parametro URL iniettato (ad es., ?--env=dev) potrebbe manipolare $_SERVER['argv'] in modo che contenga ["--env=dev"]. Questo array viene passato direttamente a detect, consentendo potenzialmente a un attaccante di controllare l'ambiente.
//Illuminate\Foundation\EnvironmentDetector
public function detect(Closure $callback, $consoleArgs = null)
{
if ($consoleArgs) {
return $this->detectConsoleEnvironment($callback, $consoleArgs);
}
return $this->detectWebEnvironment($callback);
}
Scopo: il metodo detect determina se $consoleArgs (l'array argv) è fornito. Se presente, chiama detectConsoleEnvironment per gestire il rilevamento dell'ambiente basato su console; altrimenti, chiama detectWebEnvironment per le richieste HTTP.
Percorso verso la vulnerabilità: se $_SERVER['argv'] include valori iniettati come --env=dev, si arriva a detectConsoleEnvironment, che elabora gli argomenti e potrebbe far passare l'applicazione a un ambiente diverso.
//Illuminate\Foundation\EnvironmentDetector
protected function detectConsoleEnvironment(Closure $callback, array $args)
{
// First we will check if an environment argument was passed via console arguments
// and if it was that automatically overrides as the environment. Otherwise, we
// will check the environment as a "web" request like a typical HTTP request.
if (! is_null($value = $this->getEnvironmentArgument($args))) {
return $value;
}
return $this->detectWebEnvironment($callback);
}
Scopo: questo metodo verifica se l'argomento --env è presente tra gli argomenti della console.
Meccanismo: chiama getEnvironmentArgument per vedere se uno qualsiasi degli argomenti argv specifica un ambiente. Se --env è fornito, questo metodo restituisce il valore dell'ambiente specificato, bypassando la chiamata a detectWebEnvironment.
//Illuminate\Foundation\EnvironmentDetector
protected function getEnvironmentArgument(array $args)
{
foreach ($args as $i => $value) {
if ($value === '--env') {
return $args[$i + 1] ?? null;
}
if (str_starts_with($value, '--env=')) {
return head(array_slice(explode('=', $value), 1));
}
}
}
Scopo: questo metodo analizza argv per trovare l'argomento --env. Meccanismo:
Se --env viene trovato come flag autonomo, restituisce l'argomento successivo come valore dell'ambiente.
Se viene usata la sintassi --env= (ad es., --env=dev), estrae e restituisce l'ambiente (dev in questo caso).
Configurazione dell'ambiente:
Il file .env ha APP_ENV=development, quindi per impostazione predefinita l'applicazione è impostata sull'ambiente di sviluppo.
@production
<p>Production environment</p>
@endproduction
@env ('local')
<p>Local environment</p>
@endenv
Accesso predefinito (http://localhost):
Poiché APP_ENV è impostato su development e non viene iniettato alcun argomento --env, né la direttiva @production né la direttiva @env('local') corrispondono.
Risultato: l'output è vuoto.
Argomento iniettato per la produzione (http://localhost?--env=production):
Con ?--env=production nell'URL, $_SERVER['argv'] viene manipolato per contenere ["--env=production"].
Questo attiva il meccanismo di rilevamento dell'ambiente di Laravel, impostando l'ambiente su production.
Risultato: la direttiva @production restituisce <p>Production environment</p>.
Argomento iniettato per local (http://localhost?--env=local):
Con ?--env=local, $_SERVER['argv'] include ["--env=local"], cambiando l'ambiente in local.
Risultato: la direttiva @env('local') restituisce <p>Local environment</p>
Questa vulnerabilità non consente di cambiare l'ambiente all'interno della funzione config. Invece, influisce solo sull'impostazione dell'ambiente all'interno della classe Application.
Pertanto, sebbene le direttive Blade e altre parti del codice si affidino alla classe Application per rilevare l'ambiente, il codice che utilizza la funzione config non è influenzato da questa vulnerabilità.