diff --git a/Services/StreamedCommandResponseGenerator.php b/Services/StreamedCommandResponseGenerator.php index f6cdceb..38e6f40 100644 --- a/Services/StreamedCommandResponseGenerator.php +++ b/Services/StreamedCommandResponseGenerator.php @@ -23,7 +23,13 @@ class StreamedCommandResponseGenerator public function run(array $params, callable $finish): StreamedResponse { $process = new Process($params); - $process->setEnv(['COMPOSER_HOME' => sys_get_temp_dir() . '/composer']); + /** @phpstan-ignore-next-line False prevents Symfony Process from forwarding inherited environment variables. */ + $process->setEnv([ + 'COMPOSER_HOME' => sys_get_temp_dir() . '/composer', + // The installer starts CLI commands from a web request. Symfony Runtime + // 7.4.12+ clears argv when QUERY_STRING is present, so do not forward it. + 'QUERY_STRING' => false, + ]); // Read process timeout from environment or use default value $timeout = Platform::getEnv('SHOPWARE_INSTALLER_TIMEOUT'); diff --git a/Tests/Services/StreamedCommandResponseGeneratorTest.php b/Tests/Services/StreamedCommandResponseGeneratorTest.php index b2f23e4..cc981f5 100644 --- a/Tests/Services/StreamedCommandResponseGeneratorTest.php +++ b/Tests/Services/StreamedCommandResponseGeneratorTest.php @@ -41,6 +41,30 @@ public function testRunJSON(): void static::assertSame('foo' . \PHP_EOL . '{"success":true}', $content); } + public function testRunJSONDoesNotForwardQueryStringToChildProcesses(): void + { + $_SERVER['QUERY_STRING'] = 'shopwareVersion=6.7.9999999.9999999'; + $_ENV['QUERY_STRING'] = 'shopwareVersion=6.7.9999999.9999999'; + putenv('QUERY_STRING=shopwareVersion=6.7.9999999.9999999'); + + try { + $response = (new StreamedCommandResponseGenerator())->runJSON([ + \PHP_BINARY, + '-r', + 'echo getenv("QUERY_STRING") === false ? "clean" : "leaked";', + ]); + + ob_start(); + $response->sendContent(); + $content = ob_get_clean(); + + static::assertSame('clean{"success":true}', $content); + } finally { + unset($_SERVER['QUERY_STRING'], $_ENV['QUERY_STRING']); + putenv('QUERY_STRING'); + } + } + public function testCustomTimeoutFromEnv(): void { $customTimeout = 333.0;