From 7183fc61d56e3bdd5721f784dc2baed6d3bd4d4e Mon Sep 17 00:00:00 2001 From: Ralf Lang Date: Wed, 27 May 2026 13:25:21 +0200 Subject: [PATCH] fix(security): restrict unserialize allowed_classes (ZDI-20-1051) Follow-up to horde/imp#7 Deserialization restricted to data-only with no class support for: tasklist_columns, task_alarms, task_alarm_methods, show_external, display_tasklists --- lib/Driver/Sql.php | 2 +- lib/Nag.php | 8 ++++---- lib/Task.php | 2 +- lib/View/List.php | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/Driver/Sql.php b/lib/Driver/Sql.php index c66f69c5..42d81b31 100644 --- a/lib/Driver/Sql.php +++ b/lib/Driver/Sql.php @@ -719,7 +719,7 @@ protected function _buildTask($row, $include_history = true) ?? null, 'alarm' => $row['task_alarm'], 'methods' => Horde_String::convertCharset( - @unserialize($row['task_alarm_methods']), + @unserialize($row['task_alarm_methods'], ['allowed_classes' => false]), $this->_params['charset'], 'UTF-8' ), diff --git a/lib/Nag.php b/lib/Nag.php index 26fed0b7..c99db363 100644 --- a/lib/Nag.php +++ b/lib/Nag.php @@ -251,7 +251,7 @@ public static function listTasks(array $options = []) $tasks->process(); if ($options['external'] - && ($apps = @unserialize($prefs->getValue('show_external'))) + && ($apps = @unserialize($prefs->getValue('show_external'), ['allowed_classes' => false])) && is_array($apps)) { foreach ($apps as $app) { // We look for registered apis that support listAs(taskHash). @@ -510,7 +510,7 @@ public static function listTasklists( return $tasklists; } - $display_tasklists = @unserialize($GLOBALS['prefs']->getValue('display_tasklists')); + $display_tasklists = @unserialize($GLOBALS['prefs']->getValue('display_tasklists'), ['allowed_classes' => false]); if (is_array($display_tasklists)) { foreach ($display_tasklists as $id) { try { @@ -2151,7 +2151,7 @@ protected static function _purgeActiveSyncTaskListCollections( * * @throws Horde_ActiveSync_Exception */ - public static function pruneActiveSyncTaskCache(array $allowedShareIds = null) + public static function pruneActiveSyncTaskCache(?array $allowedShareIds = null) { if (!self::_isActiveSyncEnabled() || !$GLOBALS['prefs']->getValue('activesync_no_multiplex')) { @@ -2278,7 +2278,7 @@ public static function removeTasklistFromSyncLists($tasklistId) */ protected static function _getPrefList($pref) { - $list = @unserialize($GLOBALS['prefs']->getValue($pref)); + $list = @unserialize($GLOBALS['prefs']->getValue($pref), ['allowed_classes' => false]); return is_array($list) ? array_values($list) : []; } diff --git a/lib/Task.php b/lib/Task.php index 6a41ca30..d18f7d82 100644 --- a/lib/Task.php +++ b/lib/Task.php @@ -1297,7 +1297,7 @@ public function toAlarm($user = null, $prefs = null) $prefs = $GLOBALS['prefs']; } - $methods = !empty($this->methods) ? $this->methods : @unserialize($prefs->getValue('task_alarms')); + $methods = !empty($this->methods) ? $this->methods : @unserialize($prefs->getValue('task_alarms'), ['allowed_classes' => false]); if (!$methods) { $methods = []; } diff --git a/lib/View/List.php b/lib/View/List.php index 24dc1b38..2d3d3768 100644 --- a/lib/View/List.php +++ b/lib/View/List.php @@ -131,7 +131,7 @@ public function render($output) $view->sortdir = $prefs->getValue('sortdir'); $view->sortdirclass = $view->sortdir ? 'sortup' : 'sortdown'; $view->dateFormat = $prefs->getValue('date_format'); - $view->columns = @unserialize($prefs->getValue('tasklist_columns')); + $view->columns = @unserialize($prefs->getValue('tasklist_columns'), ['allowed_classes' => false]); $view->smartShare = $this->_smartShare; $view->haveSearch = $this->_haveSearch; $view->tab_name = $this->_vars->get('tab_name', $prefs->getValue('show_completed'));