Security advisory GHSA-3p32-j457-pg5x: Query Binding Exploitation
Package: laravel/framework (composer), vulnerable version: v8.22.0, fixed in: 8.22.1
CWE: CWE-74
CWE-89
Files changed by the fix:
src/Illuminate/Database/Query/Builder.php

Fix diff:
diff --git a/src/Illuminate/Database/Query/Builder.php b/src/Illuminate/Database/Query/Builder.php
index 0d4c7c3ae16c..83416d83be02 100755
--- a/src/Illuminate/Database/Query/Builder.php
+++ b/src/Illuminate/Database/Query/Builder.php
@@ -698,7 +698,7 @@ public function where($column, $operator = null, $value = null, $boolean = 'and'
         );
 
         if (! $value instanceof Expression) {
-            $this->addBinding($value, 'where');
+            $this->addBinding(is_array($value) ? head($value) : $value, 'where');
         }
 
         return $this;
@@ -1043,7 +1043,7 @@ public function whereBetween($column, array $values, $boolean = 'and', $not = fa
 
         $this->wheres[] = compact('type', 'column', 'values', 'boolean', 'not');
 
-        $this->addBinding($this->cleanBindings($values), 'where');
+        $this->addBinding(array_slice($this->cleanBindings($values), 0, 2), 'where');
 
         return $this;
     }
@@ -1111,6 +1111,8 @@ public function whereDate($column, $operator, $value = null, $boolean = 'and')
             $value, $operator, func_num_args() === 2
         );
 
+        $value = is_array($value) ? head($value) : $value;
+
         if ($value instanceof DateTimeInterface) {
             $value = $value->format('Y-m-d');
         }
@@ -1150,6 +1152,8 @@ public function whereTime($column, $operator, $value = null, $boolean = 'and')
             $value, $operator, func_num_args() === 2
         );
 
+        $value = is_array($value) ? head($value) : $value;
+
         if ($value instanceof DateTimeInterface) {
             $value = $value->format('H:i:s');
         }
@@ -1189,6 +1193,8 @@ public function whereDay($column, $operator, $value = null, $boolean = 'and')
             $value, $operator, func_num_args() === 2
         );
 
+        $value = is_array($value) ? head($value) : $value;
+
         if ($value instanceof DateTimeInterface) {
             $value = $value->format('d');
         }
@@ -1232,6 +1238,8 @@ public function whereMonth($column, $operator, $value = null, $boolean = 'and')
             $value, $operator, func_num_args() === 2
         );
 
+        $value = is_array($value) ? head($value) : $value;
+
         if ($value instanceof DateTimeInterface) {
             $value = $value->format('m');
         }
@@ -1275,6 +1283,8 @@ public function whereYear($column, $operator, $value = null, $boolean = 'and')
             $value, $operator, func_num_args() === 2
         );
 
+        $value = is_array($value) ? head($value) : $value;
+
         if ($value instanceof DateTimeInterface) {
             $value = $value->format('Y');
         }
@@ -1583,7 +1593,7 @@ public function whereJsonLength($column, $operator, $value = null, $boolean = 'a
         $this->wheres[] = compact('type', 'column', 'operator', 'value', 'boolean');
 
         if (! $value instanceof Expression) {
-            $this->addBinding($value);
+            $this->addBinding((int) $value);
         }
 
         return $this;
@@ -1732,7 +1742,7 @@ public function having($column, $operator = null, $value = null, $boolean = 'and
         $this->havings[] = compact('type', 'column', 'operator', 'value', 'boolean');
 
         if (! $value instanceof Expression) {
-            $this->addBinding($value, 'having');
+            $this->addBinding(is_array($value) ? head($value) : $value, 'having');
         }
 
         return $this;
diff --git a/tests/Database/DatabaseQueryBuilderTest.php b/tests/Database/DatabaseQueryBuilderTest.php
index 87f7268a565b..407b312ee5bf 100755
--- a/tests/Database/DatabaseQueryBuilderTest.php
+++ b/tests/Database/DatabaseQueryBuilderTest.php
@@ -301,24 +301,24 @@ public function testBasicWheres()
     public function testWheresWithArrayValue()
     {
         $builder = $this->getBuilder();
-        $builder->select('*')->from('users')->where('id', [12, 30]);
+        $builder->select('*')->from('users')->where('id', [12]);
         $this->assertSame('select * from "users" where "id" = ?', $builder->toSql());
-        $this->assertEquals([0 => 12, 1 => 30], $builder->getBindings());
-
-        $builder = $this->getBuilder();
-        $builder->select('*')->from('users')->where('id', '=', [12, 30]);
-        $this->assertSame('select * from "users" where "id" = ?', $builder->toSql());
-        $this->assertEquals([0 => 12, 1 => 30], $builder->getBindings());
-
-        $builder = $this->getBuilder();
-        $builder->select('*')->from('users')->where('id', '!=', [12, 30]);
-        $this->assertSame('select * from "users" where "id" != ?', $builder->toSql());
-        $this->assertEquals([0 => 12, 1 => 30], $builder->getBindings());
-
-        $builder = $this->getBuilder();
-        $builder->select('*')->from('users')->where('id', '<>', [12, 30]);
-        $this->assertSame('select * from "users" where "id" <> ?', $builder->toSql());
-        $this->assertEquals([0 => 12, 1 => 30], $builder->getBindings());
+        $this->assertEquals([0 => 12], $builder->getBindings());
+
+        // $builder = $this->getBuilder();
+        // $builder->select('*')->from('users')->where('id', '=', [12, 30]);
+        // $this->assertSame('select * from "users" where "id" = ?', $builder->toSql());
+        // $this->assertEquals([0 => 12, 1 => 30], $builder->getBindings());
+
+        // $builder = $this->getBuilder();
+        // $builder->select('*')->from('users')->where('id', '!=', [12, 30]);
+        // $this->assertSame('select * from "users" where "id" != ?', $builder->toSql());
+        // $this->assertEquals([0 => 12, 1 => 30], $builder->getBindings());
+
+        // $builder = $this->getBuilder();
+        // $builder->select('*')->from('users')->where('id', '<>', [12, 30]);
+        // $this->assertSame('select * from "users" where "id" <> ?', $builder->toSql());
+        // $this->assertEquals([0 => 12, 1 => 30], $builder->getBindings());
     }
 
     public function testMySqlWrappingProtectsQuotationMarks()