Control: tags -1 patch

Hi,

I've backported upstream's fixes for version 6.x. to version 5.7,
along with a few additional lines that I believe are required to
adequately fix this for 5.7. This seems to work as far as I can tell;
upstream's test suite shows no regressions and the tests they added
along with their fixes also pass.

A patch is attached.

Regards,
Robin
From f8365784a8b5d9c3ef8ad0ce316bf056ea0eef5e Mon Sep 17 00:00:00 2001
From: Robin Gustafsson <ro...@rgson.se>
Date: Sat, 1 May 2021 15:30:35 +0200
Subject: [PATCH] Security fix: Query Binding Exploitation

Closes: #980899
CVE-2021-21263
---
 ...01-6.x-Limit-expected-bindings-35865.patch | 98 +++++++++++++++++++
 .../0002-Limit-expected-bindingx-v2.patch     | 94 ++++++++++++++++++
 ...hereDay-and-whereYear-to-clean-value.patch | 31 ++++++
 ...it-bindings-for-having-between-tests.patch | 22 +++++
 ...Clean-value-in-orWhereDay-Month-Year.patch | 42 ++++++++
 debian/patches/series                         |  5 +
 6 files changed, 292 insertions(+)
 create mode 100644 debian/patches/0001-6.x-Limit-expected-bindings-35865.patch
 create mode 100644 debian/patches/0002-Limit-expected-bindingx-v2.patch
 create mode 100644 debian/patches/0003-Update-whereDay-and-whereYear-to-clean-value.patch
 create mode 100644 debian/patches/0004-Add-limit-bindings-for-having-between-tests.patch
 create mode 100644 debian/patches/0005-Clean-value-in-orWhereDay-Month-Year.patch
 create mode 100644 debian/patches/series

diff --git a/debian/patches/0001-6.x-Limit-expected-bindings-35865.patch b/debian/patches/0001-6.x-Limit-expected-bindings-35865.patch
new file mode 100644
index 0000000000..a42ef10821
--- /dev/null
+++ b/debian/patches/0001-6.x-Limit-expected-bindings-35865.patch
@@ -0,0 +1,98 @@
+From: Taylor Otwell <tay...@laravel.com>
+Date: Wed, 13 Jan 2021 07:35:45 -0600
+Subject: [6.x] Limit expected bindings (#35865)
+
+* limit expected bindings
+
+* limit more bindings
+
+Origin: https://github.com/laravel/framework/commit/d0954f4574f315f0c2e9e65e92cc74b80eadcac1
+---
+ Query/Builder.php | 18 ++++++++++++++----
+ 1 file changed, 14 insertions(+), 4 deletions(-)
+
+diff --git a/Query/Builder.php b/Query/Builder.php
+index 4fa3c6d..0812a70 100755
+--- a/Query/Builder.php
++++ b/Query/Builder.php
+@@ -654,7 +654,7 @@ class Builder
+         );
+ 
+         if (! $value instanceof Expression) {
+-            $this->addBinding($value, 'where');
++            $this->addBinding(is_array($value) ? head($value) : $value, 'where');
+         }
+ 
+         return $this;
+@@ -1051,7 +1051,7 @@ class Builder
+ 
+         $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;
+     }
+@@ -1119,6 +1119,8 @@ class Builder
+             $value, $operator, func_num_args() === 2
+         );
+ 
++        $value = is_array($value) ? head($value) : $value;
++
+         if ($value instanceof DateTimeInterface) {
+             $value = $value->format('Y-m-d');
+         }
+@@ -1158,6 +1160,8 @@ class Builder
+             $value, $operator, func_num_args() === 2
+         );
+ 
++        $value = is_array($value) ? head($value) : $value;
++
+         if ($value instanceof DateTimeInterface) {
+             $value = $value->format('H:i:s');
+         }
+@@ -1197,6 +1201,8 @@ class Builder
+             $value, $operator, func_num_args() === 2
+         );
+ 
++        $value = is_array($value) ? head($value) : $value;
++
+         if ($value instanceof DateTimeInterface) {
+             $value = $value->format('d');
+         }
+@@ -1236,6 +1242,8 @@ class Builder
+             $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 @@ class Builder
+             $value, $operator, func_num_args() === 2
+         );
+ 
++        $value = is_array($value) ? head($value) : $value;
++
+         if ($value instanceof DateTimeInterface) {
+             $value = $value->format('Y');
+         }
+@@ -1581,7 +1591,7 @@ class Builder
+         $this->wheres[] = compact('type', 'column', 'operator', 'value', 'boolean');
+ 
+         if (! $value instanceof Expression) {
+-            $this->addBinding($value);
++            $this->addBinding((int) $value);
+         }
+ 
+         return $this;
+@@ -1714,7 +1724,7 @@ class Builder
+         $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/debian/patches/0002-Limit-expected-bindingx-v2.patch b/debian/patches/0002-Limit-expected-bindingx-v2.patch
new file mode 100644
index 0000000000..add0a09743
--- /dev/null
+++ b/debian/patches/0002-Limit-expected-bindingx-v2.patch
@@ -0,0 +1,94 @@
+From: Kane Cohen <kaneco...@gmail.com>
+Date: Thu, 21 Jan 2021 08:44:52 +0000
+Subject: Limit expected bindingx v2.
+
+Origin: https://github.com/laravel/framework/commit/9d3752ca5f29c4cb1c0384fb01847820b6ac492c
+---
+ Query/Builder.php | 25 ++++++++++++++++++-------
+ 1 file changed, 18 insertions(+), 7 deletions(-)
+
+diff --git a/Query/Builder.php b/Query/Builder.php
+index 0812a70..f18ab57 100755
+--- a/Query/Builder.php
++++ b/Query/Builder.php
+@@ -292,6 +292,17 @@ class Builder
+         return $this;
+     }
+ 
++    /**
++     * Returns scalar type value from an unknown type of input.
++     *
++     * @param  mixed  $value
++     * @return mixed
++     */
++    protected function scalarValue($value)
++    {
++        return is_array($value) ? head(Arr::flatten($value)) : $value;
++    }
++
+     /**
+      * Creates a subquery and parse it.
+      *
+@@ -654,7 +665,7 @@ class Builder
+         );
+ 
+         if (! $value instanceof Expression) {
+-            $this->addBinding(is_array($value) ? head($value) : $value, 'where');
++            $this->addBinding($this->scalarValue($value), 'where');
+         }
+ 
+         return $this;
+@@ -1051,7 +1062,7 @@ class Builder
+ 
+         $this->wheres[] = compact('type', 'column', 'values', 'boolean', 'not');
+ 
+-        $this->addBinding(array_slice($this->cleanBindings($values), 0, 2), 'where');
++        $this->addBinding(array_slice($this->cleanBindings(Arr::flatten($values)), 0, 2), 'where');
+ 
+         return $this;
+     }
+@@ -1119,7 +1130,7 @@ class Builder
+             $value, $operator, func_num_args() === 2
+         );
+ 
+-        $value = is_array($value) ? head($value) : $value;
++        $value = $this->scalarValue($value);
+ 
+         if ($value instanceof DateTimeInterface) {
+             $value = $value->format('Y-m-d');
+@@ -1160,7 +1171,7 @@ class Builder
+             $value, $operator, func_num_args() === 2
+         );
+ 
+-        $value = is_array($value) ? head($value) : $value;
++        $value = $this->scalarValue($value);
+ 
+         if ($value instanceof DateTimeInterface) {
+             $value = $value->format('H:i:s');
+@@ -1242,7 +1253,7 @@ class Builder
+             $value, $operator, func_num_args() === 2
+         );
+ 
+-        $value = is_array($value) ? head($value) : $value;
++        $value = $this->scalarValue($value);
+ 
+         if ($value instanceof DateTimeInterface) {
+             $value = $value->format('m');
+@@ -1591,7 +1602,7 @@ class Builder
+         $this->wheres[] = compact('type', 'column', 'operator', 'value', 'boolean');
+ 
+         if (! $value instanceof Expression) {
+-            $this->addBinding((int) $value);
++            $this->addBinding((int) $this->scalarValue($value));
+         }
+ 
+         return $this;
+@@ -1724,7 +1735,7 @@ class Builder
+         $this->havings[] = compact('type', 'column', 'operator', 'value', 'boolean');
+ 
+         if (! $value instanceof Expression) {
+-            $this->addBinding(is_array($value) ? head($value) : $value, 'having');
++            $this->addBinding($this->scalarValue($value), 'having');
+         }
+ 
+         return $this;
diff --git a/debian/patches/0003-Update-whereDay-and-whereYear-to-clean-value.patch b/debian/patches/0003-Update-whereDay-and-whereYear-to-clean-value.patch
new file mode 100644
index 0000000000..59aaa7aa47
--- /dev/null
+++ b/debian/patches/0003-Update-whereDay-and-whereYear-to-clean-value.patch
@@ -0,0 +1,31 @@
+From: Kane Cohen <kaneco...@gmail.com>
+Date: Thu, 21 Jan 2021 10:48:50 +0000
+Subject: Update whereDay and whereYear to clean value.
+
+Origin: https://github.com/laravel/framework/commit/dbbb1c1c8a1fa0a51677b5a74fcfe0e2561ced91
+---
+ Query/Builder.php | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/Query/Builder.php b/Query/Builder.php
+index f18ab57..79fa2e3 100755
+--- a/Query/Builder.php
++++ b/Query/Builder.php
+@@ -1212,7 +1212,7 @@ class Builder
+             $value, $operator, func_num_args() === 2
+         );
+ 
+-        $value = is_array($value) ? head($value) : $value;
++        $value = $this->scalarValue($value);
+ 
+         if ($value instanceof DateTimeInterface) {
+             $value = $value->format('d');
+@@ -1294,7 +1294,7 @@ class Builder
+             $value, $operator, func_num_args() === 2
+         );
+ 
+-        $value = is_array($value) ? head($value) : $value;
++        $value = $this->scalarValue($value);
+ 
+         if ($value instanceof DateTimeInterface) {
+             $value = $value->format('Y');
diff --git a/debian/patches/0004-Add-limit-bindings-for-having-between-tests.patch b/debian/patches/0004-Add-limit-bindings-for-having-between-tests.patch
new file mode 100644
index 0000000000..8470c1c633
--- /dev/null
+++ b/debian/patches/0004-Add-limit-bindings-for-having-between-tests.patch
@@ -0,0 +1,22 @@
+From: Kane Cohen <kaneco...@gmail.com>
+Date: Thu, 21 Jan 2021 12:08:38 +0000
+Subject: Add limit bindings for having between + tests.
+
+Origin: https://github.com/laravel/framework/commit/c6b8168e6cbbe339fdc3af5ccdded545779965df
+---
+ Query/Builder.php | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/Query/Builder.php b/Query/Builder.php
+index 79fa2e3..9ad9c4c 100755
+--- a/Query/Builder.php
++++ b/Query/Builder.php
+@@ -1773,7 +1773,7 @@ class Builder
+ 
+         $this->havings[] = compact('type', 'column', 'values', 'boolean', 'not');
+ 
+-        $this->addBinding($this->cleanBindings($values), 'having');
++        $this->addBinding(array_slice($this->cleanBindings(Arr::flatten($values)), 0, 2), 'having');
+ 
+         return $this;
+     }
diff --git a/debian/patches/0005-Clean-value-in-orWhereDay-Month-Year.patch b/debian/patches/0005-Clean-value-in-orWhereDay-Month-Year.patch
new file mode 100644
index 0000000000..b6d81de8e3
--- /dev/null
+++ b/debian/patches/0005-Clean-value-in-orWhereDay-Month-Year.patch
@@ -0,0 +1,42 @@
+From: Robin Gustafsson <ro...@rgson.se>
+Date: Sat, 1 May 2021 15:52:36 +0200
+Subject: Clean value in orWhereDay/Month/Year
+
+In 6.x these methods call the whereDay/Month/Year methods where
+the value is cleaned. In 5.x they don't, and so the value must
+be cleaned here too.
+---
+ Query/Builder.php | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/Query/Builder.php b/Query/Builder.php
+index 9ad9c4c..74222c7 100755
+--- a/Query/Builder.php
++++ b/Query/Builder.php
+@@ -1235,6 +1235,8 @@ class Builder
+             $value, $operator, func_num_args() === 2
+         );
+ 
++        $value = $this->scalarValue($value);
++
+         return $this->addDateBasedWhere('Day', $column, $operator, $value, 'or');
+     }
+ 
+@@ -1276,6 +1278,8 @@ class Builder
+             $value, $operator, func_num_args() === 2
+         );
+ 
++        $value = $this->scalarValue($value);
++
+         return $this->addDateBasedWhere('Month', $column, $operator, $value, 'or');
+     }
+ 
+@@ -1317,6 +1321,8 @@ class Builder
+             $value, $operator, func_num_args() === 2
+         );
+ 
++        $value = $this->scalarValue($value);
++
+         return $this->addDateBasedWhere('Year', $column, $operator, $value, 'or');
+     }
+ 
diff --git a/debian/patches/series b/debian/patches/series
new file mode 100644
index 0000000000..ca17381904
--- /dev/null
+++ b/debian/patches/series
@@ -0,0 +1,5 @@
+0001-6.x-Limit-expected-bindings-35865.patch
+0002-Limit-expected-bindingx-v2.patch
+0003-Update-whereDay-and-whereYear-to-clean-value.patch
+0004-Add-limit-bindings-for-having-between-tests.patch
+0005-Clean-value-in-orWhereDay-Month-Year.patch
-- 
2.20.1

Reply via email to