[horde] another security issue discovered in Horde ref. CVE-2022-30287

Jens Wahnes wahnes at uni-koeln.de
Tue Jun 14 11:54:08 UTC 2022


Christoph Haas wrote:
> So on Linux I would do:
> root at myhorde:/# cd /tmp
> root at myhorde:/tmp# git clone https://github.com/UnivParis1/turba.git
> root at myhorde:/tmp/turba# git reset --hard 
> 9f2521328aa7d0dbd905591eca138c8e7580d673
> and copy all patched files to my webroot.
> 
> --> what "manual tweeking" in "horde/turba/lib/Application.ini has to be 
> done?
> And what "fuzz" is with the other files?

My approach was a bit different. I tried to apply the _changes_ that 
Pascal Rigaux introduced to the code of the master branch (i.e. Horde 6) 
to the code of Horde 5 (that would be FRAMEWORK_5_2 in Git). I did not 
attempt to copy over the whole files from the Horde 6 branch. I don't 
think that doing so could actually work. Too much has changed in Horde 6 
to get a combination of working code this way.

So what I did was basically to download Pascal's changes as a patch file 
(i.e. "wget -N 
https://github.com/horde/turba/commit/784da95e0190321b08ceeb27e2cb6c7505f2057c.patch") 
and then modify this patch set so that it can be applied to Horde 5 code.

This modification includes throwing out the code for 
"turba-import-openxchange", which does not exist in Horde 5, like you 
mentioned. The modifications to the turba/lib/Application.php in that 
patch set need to be re-written as this file differs too much in between 
the Horde 5 and Horde 6 codebase. I'll attach the patch file that I 
ended up with here.

This modified patch can then be applied to the Turba 4.2.25 codebase by 
changing into the directory where the Pear installation of Turba resides 
(e.g. "chdir /var/www/horde/turba") and applying the patch via
patch -p1 < 784da95e0190321b08ceeb27e2cb6c7505f2057c.modified.patch

> Or could I solve all the trouble through PEAR-upgrade to Turba 4.2.28?

For me, version 4.2.28 did not fix the problem, at least not for all 
users on our site. There may be some issue specific to certain 
preference settings or the like; I have not been able to find out why it 
works for some users but not for others.


Jens
-------------- next part --------------
From 784da95e0190321b08ceeb27e2cb6c7505f2057c Mon Sep 17 00:00:00 2001
From: Pascal Rigaux <pascal.rigaux at univ-paris1.fr>
Date: Thu, 2 Jun 2022 13:14:39 +0200
Subject: [PATCH] fix CVE-2022-30287

---
 bin/turba-import-openxchange   |  2 +-
 lib/Api.php                    | 14 +++++++-------
 lib/Application.php            |  4 ++--
 lib/Driver/Share.php           |  2 +-
 lib/Driver/Vbook.php           |  2 +-
 lib/Factory/Driver.php         | 11 ++++++++++-
 lib/Form/CreateAddressBook.php |  2 +-
 lib/Turba.php                  |  2 +-
 8 files changed, 24 insertions(+), 15 deletions(-)

diff --git a/lib/Api.php b/lib/Api.php
index f148028b..fc9033f8 100644
--- a/lib/Api.php
+++ b/lib/Api.php
@@ -456,7 +456,7 @@ public function listUids($sources = null)
 
         foreach ($this->_getSources($sources) as $source) {
             try {
-                $results = $driver->create($source)->search(array());
+                $results = $driver->createTrusted($source)->search(array());
             } catch (Turba_Exception $e) {
                 throw new Turba_Exception(sprintf(_("Error searching the address book: %s"), $e->getMessage()));
             }
@@ -511,7 +511,7 @@ public function listBy($action, $timestamp, $sources = null, $end = null, $isMod
         }
 
         foreach ($this->_getSources($sources) as $source) {
-            $sdriver = $driver->create($source);
+            $sdriver = $driver->createTrusted($source);
             if (!$isModSeq) {
                 $histories = $history->getByTimestamp(
                     '>', $timestamp, $filter,
@@ -613,11 +613,11 @@ public function getActionTimestamp($uid, $action, $sources = null, $modSeq = fal
         foreach ($this->_getSources($sources) as $source) {
             if (!$modSeq) {
                 $ts = $history->getActionTimestamp(
-                    'turba:' . $driver->create($source)->getName() . ':' . $uid,
+                    'turba:' . $driver->createTrusted($source)->getName() . ':' . $uid,
                     $action);
             } else {
                 $ts = $history->getActionModSeq(
-                    'turba:' . $driver->create($source)->getName() . ':' . $uid,
+                    'turba:' . $driver->createTrusted($source)->getName() . ':' . $uid,
                     $action);
             }
             if (!empty($ts) && $ts > $last) {
@@ -1032,7 +1032,7 @@ public function delete($uid, $sources = null)
         $driver = $GLOBALS['injector']->getInstance('Turba_Factory_Driver');
 
         foreach ($this->_getSources($sources) as $source) {
-            $sdriver = $driver->create($source);
+            $sdriver = $driver->createTrusted($source);
 
             if (!$GLOBALS['registry']->isAdmin() &&
                 !$sdriver->hasPermission(Horde_Perms::DELETE)) {
@@ -1263,7 +1263,7 @@ public function search($names = null, array $opts = array())
                 );
             }
 
-            $sdriver = $driver->create($source);
+            $sdriver = $driver->createTrusted($source);
             foreach ($names as $name) {
                 $trimname = trim($name);
                 $out = $criteria = array();
@@ -2435,7 +2435,7 @@ public function searchTags($names, $max = 10, $from = 0,
             try {
                 $driver = $injector->getInstance('Turba_Factory_Driver');
                 foreach ($this->_getSources($sources) as $source) {
-                    $sdriver = $driver->create($source);
+                    $sdriver = $driver->createTrusted($source);
                     if (!$sdriver->hasPermission(Horde_Perms::READ)) {
                         continue;
                     }
--- turba/lib/Application.php.BCK	2021-09-15 13:03:37.411694638 +0200
+++ turba/lib/Application.php	2022-06-03 11:06:41.333084893 +0200
@@ -357,7 +357,7 @@
                 try {
                     $driver = $GLOBALS['injector']
                         ->getInstance('Turba_Factory_Driver')
-                        ->create($source, $sourceId);
+                        ->createTrusted($source, $sourceId);
                 } catch (Turba_Exception $e) {
                     Horde::log($e, 'ERR');
                     continue;
@@ -397,7 +397,7 @@
             try {
                 $driver = $GLOBALS['injector']
                     ->getInstance('Turba_Factory_Driver')
-                    ->create($config, $share->getName(), $sources);
+                    ->createTrusted($config, $share->getName(), $sources);
             } catch (Turba_Exception $e) {
                 continue;
             }
diff --git a/lib/Driver/Share.php b/lib/Driver/Share.php
index 4035c9d6..dc060185 100644
--- a/lib/Driver/Share.php
+++ b/lib/Driver/Share.php
@@ -44,7 +44,7 @@ public function __construct($name = '', array $params = array())
     {
         parent::__construct($name, $params);
         $this->_share = $this->_params['config']['params']['share'];
-        $this->_driver = $GLOBALS['injector']->getInstance('Turba_Factory_Driver')->create($this->_params['config'], $name);
+        $this->_driver = $GLOBALS['injector']->getInstance('Turba_Factory_Driver')->createTrusted($this->_params['config'], $name);
         $this->_driver->setContactOwner($this->_getContactOwner());
         $this->_driver->setSourceName($name);
     }
diff --git a/lib/Driver/Vbook.php b/lib/Driver/Vbook.php
index 06ff5a12..df13c873 100644
--- a/lib/Driver/Vbook.php
+++ b/lib/Driver/Vbook.php
@@ -55,7 +55,7 @@ public function __construct($name = '', array $params = array())
         /* Load the underlying driver. */
         $this->_driver = $GLOBALS['injector']
             ->getInstance('Turba_Factory_Driver')
-            ->create($this->_params['source']);
+            ->createTrusted($this->_params['source']);
 
         $this->searchCriteria = empty($this->_params['criteria'])
             ? array()
diff --git a/lib/Factory/Driver.php b/lib/Factory/Driver.php
index 29f54ab9..0bcfccd9 100644
--- a/lib/Factory/Driver.php
+++ b/lib/Factory/Driver.php
@@ -32,6 +32,15 @@ class Turba_Factory_Driver extends Horde_Core_Factory_Base
      */
     private $_instances = array();
 
+    public function create($name)
+    {
+        if (is_array($name)) {
+            error_log("Disallowed for CVE-2022-30287: " . json_encode(debug_backtrace()));
+            die("not allowed");
+        }
+        return $this->createTrusted($name);
+    }
+
     /**
      * Return the Turba_Driver:: instance.
      *
@@ -48,7 +57,7 @@ class Turba_Factory_Driver extends Horde_Core_Factory_Base
      * @return Turba_Driver  The singleton instance.
      * @throws Turba_Exception
      */
-    public function create($name, $name2 = '', $cfgSources = array())
+    public function createTrusted($name, $name2 = '', $cfgSources = array())
     {
         if (empty($cfgSources)) {
             $cfgSources = $GLOBALS['cfgSources'];
diff --git a/lib/Form/CreateAddressBook.php b/lib/Form/CreateAddressBook.php
index 496e7f2b..83d2faad 100644
--- a/lib/Form/CreateAddressBook.php
+++ b/lib/Form/CreateAddressBook.php
@@ -37,7 +37,7 @@ public function execute()
         $cfgSources = Turba::availableSources();
         $driver = $GLOBALS['injector']
             ->getInstance('Turba_Factory_Driver')
-            ->create($cfgSources[$GLOBALS['conf']['shares']['source']]);
+            ->createTrusted($cfgSources[$GLOBALS['conf']['shares']['source']]);
         $params = array(
             'params' => array('source' => $GLOBALS['conf']['shares']['source']),
             'name' => $this->_vars->get('name'),
diff --git a/lib/Turba.php b/lib/Turba.php
index 92f0b3d7..0f04e1e9 100644
--- a/lib/Turba.php
+++ b/lib/Turba.php
@@ -465,7 +465,7 @@ public static function permissionsFilter(array $in,
                 continue;
             }
             try {
-                $driver = $factory->create($source, $sourceId);
+                $driver = $factory->createTrusted($source, $sourceId);
                 if ($driver->hasPermission($permission) &&
                     (empty($options['require_add']) || $driver->canAdd())) {
                     $out[$sourceId] = $source;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 5324 bytes
Desc: S/MIME Cryptographic Signature
URL: <https://lists.horde.org/archives/horde/attachments/20220614/bd52d5b4/attachment-0001.bin>


More information about the horde mailing list