CVE-2024-24753: Interpretation Conflict (CWE-436)
value: Bref enable serverless PHP on AWS Lambda. When Bref is used in combination with an API Gateway with the v2 format, it does not handle multiple values headers. If PHP generates a response with two headers having the same key but different values only the latest one is kept. If an application relies on multiple headers with the same key being set for security reasons, then Bref would lower the application security. For example, if an application sets multiple `Content-Security-Policy` headers, then Bref would just reflect the latest one. This vulnerability is patched in 2.1.13.
CWE description: Product A handles inputs or steps differently than Product B, which causes A to perform incorrect actions based on its perception of B's state.
CVSS v3 base score: 6.5
Published: 2024-02-01T16:17Z
Repository: https://github.com/brefphp/bref
Language: PHP
Files changed: src/Event/Http/HttpResponse.php, tests/Event/Http/HttpResponseTest.php
Commit date: 2024-01-31 11:23:56 +0100
Commit message: Add support for multi-value response headers with API Gateway v2

Diff: diff --git a/src/Event/Http/HttpResponse.php b/src/Event/Http/HttpResponse.php
index 7129f907..80a679bc 100644
--- a/src/Event/Http/HttpResponse.php
+++ b/src/Event/Http/HttpResponse.php
@@ -70,11 +70,11 @@ final class HttpResponse
             if ($name === 'Set-Cookie') {
                 $cookies = is_array($values) ? $values : [$values];
             } else {
                 // Make sure the values are never arrays
                 // because API Gateway v2 does not support multi-value headers
-                $headers[$name] = is_array($values) ? end($values) : $values;
+                $headers[$name] = is_array($values) ? implode(', ', $values) : $values;
             }
         }
 
         // The headers must be a JSON object. If the PHP array is empty it is
         // serialized to `[]` (we want `{}`) so we force it to an empty object.
diff --git a/tests/Event/Http/HttpResponseTest.php b/tests/Event/Http/HttpResponseTest.php
index 5dcc53cb..dab15792 100644
--- a/tests/Event/Http/HttpResponseTest.php
+++ b/tests/Event/Http/HttpResponseTest.php
@@ -56,11 +56,11 @@ class HttpResponseTest extends TestCase
             'headers' => ['X-Foo-Bar' => 'baz'],
             'body' => '',
         ], $response->toApiGatewayFormatV2());
     }
 
-    public function test nested arrays in headers are flattened()
+    public function test multi value headers()
     {
         $response = new HttpResponse('', [
             'foo' => ['bar', 'baz'],
         ]);
 
@@ -74,12 +74,14 @@ class HttpResponseTest extends TestCase
 
         self::assertEquals([
             'cookies' => [],
             'isBase64Encoded' => false,
             'statusCode' => 200,
-            // The last value is kept (when multiheaders are not enabled)
-            'headers' => ['Foo' => 'baz'],
+            // Headers are joined with a comma
+            // See https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.2
+            // API Gateway v2 does not support multi-value headers
+            'headers' => ['Foo' => 'bar, baz'],
             'body' => '',
         ], $response->toApiGatewayFormatV2());
     }
 
     public function test empty headers are considered objects()

Vulnerable code:                 $headers[$name] = is_array($values) ? end($values) : $values;
    public function test nested arrays in headers are flattened()
            // The last value is kept (when multiheaders are not enabled)
            'headers' => ['Foo' => 'baz'],
Fixed code:                 $headers[$name] = is_array($values) ? implode(', ', $values) : $values;
    public function test multi value headers()
            // Headers are joined with a comma
            // See https://datatracker.ietf.org/doc/html/rfc7230#section-3.2.2
            // API Gateway v2 does not support multi-value headers
            'headers' => ['Foo' => 'bar, baz'],