
Esta vulnerabilidad se basa en la vulnerabilidad CVE-2024-50340
La opción register_argc_argv debe estar habilitada en el archivo de configuración de PHP (php.ini). Este ajuste carga los argumentos de la línea de comandos y los parámetros de consulta en $_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);
}
Propósito: Este método detecta el entorno accediendo a $_SERVER['argv'], que contiene los argumentos de la línea de comandos, y luego delega en la clase EnvironmentDetector.
Origen de la vulnerabilidad: Al depender de $_SERVER['argv'], cualquier parámetro de URL inyectado (p. ej., ?--env=dev) podría manipular $_SERVER['argv'] para que contenga ["--env=dev"]. Este array se pasa directamente a detect, lo que potencialmente permite a un atacante controlar el entorno.
//Illuminate\Foundation\EnvironmentDetector
public function detect(Closure $callback, $consoleArgs = null)
{
if ($consoleArgs) {
return $this->detectConsoleEnvironment($callback, $consoleArgs);
}
return $this->detectWebEnvironment($callback);
}
Propósito: El método detect determina si $consoleArgs (el array argv) está presente. Si lo está, llama a detectConsoleEnvironment para manejar la detección de entorno basada en consola; de lo contrario, llama a detectWebEnvironment para solicitudes HTTP.
Vía hacia la vulnerabilidad: Si $_SERVER['argv'] incluye valores inyectados como --env=dev, se llega a detectConsoleEnvironment, que procesa los argumentos y podría cambiar la aplicación a un entorno diferente.
//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);
}
Propósito: Este método comprueba si el argumento --env está presente entre los argumentos de consola.
Mecanismo: Llama a getEnvironmentArgument para ver si alguno de los argumentos argv especifica un entorno. Si se proporciona --env, este método devuelve el valor de entorno especificado, omitiendo la llamada 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));
}
}
}
Propósito: Este método analiza argv para encontrar el argumento --env. Mecanismo:
Si --env se encuentra como una bandera independiente, devuelve el siguiente argumento como valor del entorno.
Si se utiliza la sintaxis --env= (p. ej., --env=dev), extrae y devuelve el entorno (dev en este caso).
Configuración del entorno:
El archivo .env tiene APP_ENV=development, por lo que, por defecto, la aplicación está configurada en el entorno de desarrollo.
@production
<p>Production environment</p>
@endproduction
@env ('local')
<p>Local environment</p>
@endenv
Acceso predeterminado (http://localhost):
Dado que APP_ENV está configurado como development y no se inyecta ningún argumento --env, ni la directiva @production ni la de @env('local') coinciden.
Resultado: La salida está vacía.
Argumento inyectado para producción (http://localhost?--env=production):
Con ?--env=production en la URL, $_SERVER['argv'] se manipula para que contenga ["--env=production"].
Esto activa el mecanismo de detección de entorno de Laravel, estableciendo el entorno en producción.
Resultado: La directiva @production genera <p>Production environment</p>.
Argumento inyectado para local (http://localhost?--env=local):
Con ?--env=local, $_SERVER['argv'] incluye ["--env=local"], cambiando el entorno a local.
Resultado: La directiva @env('local') genera <p>Local environment</p>
Esta vulnerabilidad no permite cambiar el entorno dentro de la función config. En cambio, solo afecta la configuración del entorno dentro de la clase Application.
Por lo tanto, aunque las directivas de Blade y otras partes del código dependen de la clase Application para detectar el entorno, el código que usa la función config no se ve afectado por esta vulnerabilidad.