From 3309a6f804daf1ca747cb9b08a77aa6c643cf0da Mon Sep 17 00:00:00 2001 From: Matthew Keeler Date: Thu, 20 Nov 2025 11:33:59 -0500 Subject: [PATCH 01/10] fix: Escape all headers in curl event publisher --- src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php b/src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php index c3d530ad..ce32299e 100644 --- a/src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php +++ b/src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php @@ -86,11 +86,7 @@ private function createCurlArgs(string $payload): string $args.= " --max-time " . $this->_timeout; foreach ($this->_eventHeaders as $key => $value) { - if ($key == 'Authorization') { - $args.= " -H " . escapeshellarg("Authorization: " . $value); - } else { - $args.= " -H '$key: $value'"; - } + $args.= " -H " . escapeshellarg("$key: $value"); } $args.= " -d " . escapeshellarg($payload); From 133cf0491274443cc495777ab59f1c877517d9b5 Mon Sep 17 00:00:00 2001 From: Matthew Keeler Date: Thu, 20 Nov 2025 11:51:39 -0500 Subject: [PATCH 02/10] Add some additional escaping --- src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php b/src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php index ce32299e..59887bc0 100644 --- a/src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php +++ b/src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php @@ -51,8 +51,8 @@ public function __construct(string $sdkKey, array $options = []) } $this->_eventHeaders = Util::eventHeaders($sdkKey, $options); - $this->_connectTimeout = $options['connect_timeout']; - $this->_timeout = $options['timeout']; + $this->_connectTimeout = intval($options['connect_timeout']); + $this->_timeout = intval($options['timeout']); $this->_isWindows = PHP_OS_FAMILY == 'Windows'; } @@ -100,7 +100,7 @@ private function createCurlArgs(string $payload): string private function makeCurlRequest(string $args): bool { $cmd = $this->_curl . " " . $args . ">> /dev/null 2>&1 &"; - shell_exec($cmd); + shell_exec(escapeshellcmd($cmd)); return true; } @@ -116,7 +116,7 @@ private function createPowershellArgs(string $payloadFile): string $args.= " -Method POST"; $args.= " -UseBasicParsing"; $args.= " -InFile $payloadFile"; - $args.= " -H @{" . $headerString . "}"; + $args.= " -H " . escapeshellarg("@{" . $headerString . "}"); $args.= " -Uri " . escapeshellarg($scheme . $this->_host . ":" . $this->_port . $this->_path . "/bulk"); $args.= " ; Remove-Item $payloadFile"; From 22d80be4a1cc58c60def07a493f25ff2f133f288 Mon Sep 17 00:00:00 2001 From: Matthew Keeler Date: Thu, 20 Nov 2025 11:55:35 -0500 Subject: [PATCH 03/10] remove full shell escape --- src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php b/src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php index 59887bc0..c129d020 100644 --- a/src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php +++ b/src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php @@ -100,7 +100,7 @@ private function createCurlArgs(string $payload): string private function makeCurlRequest(string $args): bool { $cmd = $this->_curl . " " . $args . ">> /dev/null 2>&1 &"; - shell_exec(escapeshellcmd($cmd)); + shell_exec($cmd); return true; } From 64322991f034cdadb2f16ad5cfc3090d148a5d1b Mon Sep 17 00:00:00 2001 From: Matthew Keeler Date: Thu, 20 Nov 2025 11:59:16 -0500 Subject: [PATCH 04/10] remove window escape --- src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php b/src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php index c129d020..f0adacc1 100644 --- a/src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php +++ b/src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php @@ -116,7 +116,7 @@ private function createPowershellArgs(string $payloadFile): string $args.= " -Method POST"; $args.= " -UseBasicParsing"; $args.= " -InFile $payloadFile"; - $args.= " -H " . escapeshellarg("@{" . $headerString . "}"); + $args.= " -H @{" . $headerString . "}"; $args.= " -Uri " . escapeshellarg($scheme . $this->_host . ":" . $this->_port . $this->_path . "/bulk"); $args.= " ; Remove-Item $payloadFile"; From a1f6ca3cb01c40edc890527478b20d0b51550c9e Mon Sep 17 00:00:00 2001 From: Matthew Keeler Date: Thu, 20 Nov 2025 12:26:02 -0500 Subject: [PATCH 05/10] escape curl command --- src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php b/src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php index f0adacc1..99218a47 100644 --- a/src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php +++ b/src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php @@ -47,7 +47,7 @@ public function __construct(string $sdkKey, array $options = []) $this->_path = $url['path'] ?? ''; if (array_key_exists('curl', $options)) { - $this->_curl = $options['curl']; + $this->_curl = escapeshellcmd($options['curl']); } $this->_eventHeaders = Util::eventHeaders($sdkKey, $options); From 4e2544225cd48216c2a1a70ca60377b5c7aecd2c Mon Sep 17 00:00:00 2001 From: Matthew Keeler Date: Thu, 20 Nov 2025 13:12:51 -0500 Subject: [PATCH 06/10] windows escaping --- .../Impl/Integrations/CurlEventPublisher.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php b/src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php index 99218a47..53d68392 100644 --- a/src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php +++ b/src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php @@ -108,17 +108,19 @@ private function createPowershellArgs(string $payloadFile): string { $headerString = ""; foreach ($this->_eventHeaders as $key => $value) { - $headerString .= sprintf("'%s'='%s';", $key, $value); + $escapedKey = str_replace("'", "''", $key); + $escapedValue = str_replace("'", "''", $value); + $headerString .= sprintf('"%s"="%s";', $escapedKey, $escapedValue); } $scheme = $this->_ssl ? "https://" : "http://"; $args = " Invoke-WebRequest"; $args.= " -Method POST"; $args.= " -UseBasicParsing"; - $args.= " -InFile $payloadFile"; - $args.= " -H @{" . $headerString . "}"; + $args.= " -InFile '$payloadFile'"; + $args.= " -H '@{" . $headerString . "}'"; $args.= " -Uri " . escapeshellarg($scheme . $this->_host . ":" . $this->_port . $this->_path . "/bulk"); - $args.= " ; Remove-Item $payloadFile"; + $args.= " ; Remove-Item '$payloadFile'"; return $args; } From f01f3060c54dadc01669687be61ab658f9365faa Mon Sep 17 00:00:00 2001 From: Matthew Keeler Date: Thu, 20 Nov 2025 13:16:18 -0500 Subject: [PATCH 07/10] Use strval of header value --- src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php b/src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php index 53d68392..a989fdd7 100644 --- a/src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php +++ b/src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php @@ -109,7 +109,7 @@ private function createPowershellArgs(string $payloadFile): string $headerString = ""; foreach ($this->_eventHeaders as $key => $value) { $escapedKey = str_replace("'", "''", $key); - $escapedValue = str_replace("'", "''", $value); + $escapedValue = str_replace("'", "''", strval($value)); $headerString .= sprintf('"%s"="%s";', $escapedKey, $escapedValue); } From d7efa8f3c04811bb1b12446f070e68bd6ad5b474 Mon Sep 17 00:00:00 2001 From: Matthew Keeler Date: Thu, 20 Nov 2025 13:25:43 -0500 Subject: [PATCH 08/10] debugging --- src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php b/src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php index a989fdd7..c89e949b 100644 --- a/src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php +++ b/src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php @@ -73,6 +73,7 @@ public function publish(string $payload): bool }; $args = $this->createPowershellArgs($tmpfile); + echo "@@@@@ power shell arguments are $args" . PHP_EOL; $this->makePowershellRequest($args); return true; From 60121a36788a7b7500de4267fbe5c77277a7df10 Mon Sep 17 00:00:00 2001 From: Matthew Keeler Date: Thu, 20 Nov 2025 13:31:00 -0500 Subject: [PATCH 09/10] adjustment --- src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php b/src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php index c89e949b..d272c558 100644 --- a/src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php +++ b/src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php @@ -111,7 +111,7 @@ private function createPowershellArgs(string $payloadFile): string foreach ($this->_eventHeaders as $key => $value) { $escapedKey = str_replace("'", "''", $key); $escapedValue = str_replace("'", "''", strval($value)); - $headerString .= sprintf('"%s"="%s";', $escapedKey, $escapedValue); + $headerString .= sprintf("'%s'='%s';", $escapedKey, $escapedValue); } $scheme = $this->_ssl ? "https://" : "http://"; @@ -119,7 +119,7 @@ private function createPowershellArgs(string $payloadFile): string $args.= " -Method POST"; $args.= " -UseBasicParsing"; $args.= " -InFile '$payloadFile'"; - $args.= " -H '@{" . $headerString . "}'"; + $args.= " -H @{" . $headerString . "}"; $args.= " -Uri " . escapeshellarg($scheme . $this->_host . ":" . $this->_port . $this->_path . "/bulk"); $args.= " ; Remove-Item '$payloadFile'"; From a5b4711e561a4ee6fb773413a0895b9bf1408e41 Mon Sep 17 00:00:00 2001 From: Matthew Keeler Date: Thu, 20 Nov 2025 13:33:46 -0500 Subject: [PATCH 10/10] remove debugging --- src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php b/src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php index d272c558..51dfdae7 100644 --- a/src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php +++ b/src/LaunchDarkly/Impl/Integrations/CurlEventPublisher.php @@ -73,7 +73,6 @@ public function publish(string $payload): bool }; $args = $this->createPowershellArgs($tmpfile); - echo "@@@@@ power shell arguments are $args" . PHP_EOL; $this->makePowershellRequest($args); return true;