Skip to content

Commit 066b603

Browse files
committed
fix(security): restrict unserialize allowed_classes (ZDI-20-1051)
Follow-up to #7 Allow only these classes when deserializing: - msgflags: IMP_Flag_User, IMP_Flag_Imap_*, IMP_Flag_System_* - filter: IMP_Search_Filter, IMP_Search_Element_* - vfolder: IMP_Search_Vfolder, IMP_Search_Vfolder_Vinbox, IMP_Search_Vfolder_Vtrash, IMP_Search_Element_* - remote: IMP_Remote_Account - mailbox list cache: IMP_Mailbox_List, IMP_Mailbox_List_Virtual, IMP_Mailbox_List_Pop3 Deserialization restricted to data-only (no class support) for: reply_lang, expanded_folders, nav_poll, stationery
1 parent c8e09fb commit 066b603

8 files changed

Lines changed: 86 additions & 10 deletions

File tree

lib/Compose.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -821,7 +821,7 @@ public function buildAndSendMessage(
821821
));
822822

823823
/* Add preferred reply language(s). */
824-
if ($lang = @unserialize($prefs->getValue('reply_lang'))) {
824+
if ($lang = @unserialize($prefs->getValue('reply_lang'), ['allowed_classes' => false])) {
825825
$headers->addHeader('Accept-Language', implode(',', $lang));
826826
}
827827

lib/Factory/MailboxList.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,11 @@ public function create($mailbox)
5656
$mailbox = IMP_Mailbox::get($mailbox);
5757

5858
if ($ob = $this->_getCache($mailbox)->get($key)) {
59-
$ob = @unserialize($ob);
59+
$ob = @unserialize($ob, ['allowed_classes' => [
60+
'IMP_Mailbox_List',
61+
'IMP_Mailbox_List_Virtual',
62+
'IMP_Mailbox_List_Pop3',
63+
]]);
6064
}
6165

6266
if (!$ob) {

lib/Flags.php

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,25 @@ public function __construct()
7272
}
7373

7474
if ($f_list = $GLOBALS['prefs']->getValue('msgflags')) {
75-
$f_list = @unserialize($f_list);
75+
$f_list = @unserialize($f_list, ['allowed_classes' => [
76+
'IMP_Flag_User',
77+
'IMP_Flag_Imap_Answered',
78+
'IMP_Flag_Imap_Deleted',
79+
'IMP_Flag_Imap_Draft',
80+
'IMP_Flag_Imap_Flagged',
81+
'IMP_Flag_Imap_Forwarded',
82+
'IMP_Flag_Imap_Junk',
83+
'IMP_Flag_Imap_NotJunk',
84+
'IMP_Flag_Imap_Seen',
85+
'IMP_Flag_System_Attachment',
86+
'IMP_Flag_System_Encrypted',
87+
'IMP_Flag_System_HighPriority',
88+
'IMP_Flag_System_List',
89+
'IMP_Flag_System_LowPriority',
90+
'IMP_Flag_System_Personal',
91+
'IMP_Flag_System_Signed',
92+
'IMP_Flag_System_Unseen',
93+
]]);
7694
if (is_array($f_list)) {
7795
foreach ($f_list as $val) {
7896
$this->_userflags[$val->id] = $val;

lib/Ftree/Prefs/Expanded.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public function __construct()
4242
{
4343
global $prefs;
4444

45-
if (($folders = @unserialize($prefs->getValue('expanded_folders')))
45+
if (($folders = @unserialize($prefs->getValue('expanded_folders'), ['allowed_classes' => false]))
4646
&& is_array($folders)) {
4747
$this->_data = $folders;
4848
}

lib/Ftree/Prefs/Poll.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public function __construct(IMP_Ftree $ftree)
4848
$this->_data = ['INBOX' => 1];
4949

5050
/* Add the list of polled mailboxes from the prefs. */
51-
if ($nav_poll = @unserialize($prefs->getValue('nav_poll'))) {
51+
if ($nav_poll = @unserialize($prefs->getValue('nav_poll'), ['allowed_classes' => false])) {
5252
$this->_data += $nav_poll;
5353
}
5454

lib/LoginTasks/SystemTask/Upgrade.php

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,24 @@ protected function _upgradeVirtualFolders()
345345

346346
$vfolders = $prefs->getValue('vfolder');
347347
if (!empty($vfolders)) {
348-
$vfolders = @unserialize($vfolders);
348+
$vfolders = @unserialize($vfolders, ['allowed_classes' => [
349+
'IMP_Search_Vfolder_Vinbox',
350+
'IMP_Search_Vfolder_Vtrash',
351+
'IMP_Search_Element_Attachment',
352+
'IMP_Search_Element_Autogenerated',
353+
'IMP_Search_Element_Bulk',
354+
'IMP_Search_Element_Contacts',
355+
'IMP_Search_Element_Daterange',
356+
'IMP_Search_Element_Flag',
357+
'IMP_Search_Element_Header',
358+
'IMP_Search_Element_Mailinglist',
359+
'IMP_Search_Element_Or',
360+
'IMP_Search_Element_Personal',
361+
'IMP_Search_Element_Recipient',
362+
'IMP_Search_Element_Size',
363+
'IMP_Search_Element_Text',
364+
'IMP_Search_Element_Within',
365+
]]);
349366
}
350367

351368
if (empty($vfolders) || !is_array($vfolders)) {
@@ -578,7 +595,7 @@ protected function _upgradeStationeryToTemplates()
578595
{
579596
global $injector, $prefs;
580597

581-
$slist = @unserialize($prefs->getValue('stationery'));
598+
$slist = @unserialize($prefs->getValue('stationery'), ['allowed_classes' => false]);
582599
if (is_array($slist)) {
583600
/* Old entry format:
584601
* 'c' => (string) Content

lib/Remote.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,10 @@ class IMP_Remote implements ArrayAccess, IteratorAggregate
3838
*/
3939
public function __construct()
4040
{
41-
$this->_accounts = @unserialize($GLOBALS['prefs']->getValue('remote')) ?: [];
41+
$this->_accounts = @unserialize(
42+
$GLOBALS['prefs']->getValue('remote'),
43+
['allowed_classes' => ['IMP_Remote_Account']]
44+
) ?: [];
4245
}
4346

4447
/**

lib/Search.php

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,23 @@ protected function _getFilters()
207207
}
208208

209209
if ($f_list = $GLOBALS['prefs']->getValue('filter')) {
210-
$f_list = @unserialize($f_list);
210+
$f_list = @unserialize($f_list, ['allowed_classes' => [
211+
'IMP_Search_Filter',
212+
'IMP_Search_Element_Attachment',
213+
'IMP_Search_Element_Autogenerated',
214+
'IMP_Search_Element_Bulk',
215+
'IMP_Search_Element_Contacts',
216+
'IMP_Search_Element_Daterange',
217+
'IMP_Search_Element_Flag',
218+
'IMP_Search_Element_Header',
219+
'IMP_Search_Element_Mailinglist',
220+
'IMP_Search_Element_Or',
221+
'IMP_Search_Element_Personal',
222+
'IMP_Search_Element_Recipient',
223+
'IMP_Search_Element_Size',
224+
'IMP_Search_Element_Text',
225+
'IMP_Search_Element_Within',
226+
]]);
211227
if (is_array($f_list)) {
212228
foreach ($f_list as $val) {
213229
if ($val instanceof IMP_Search_Filter) {
@@ -297,7 +313,25 @@ protected function _getVFolders()
297313
}
298314

299315
if ($pref_vf = $GLOBALS['prefs']->getValue('vfolder')) {
300-
$pref_vf = @unserialize($pref_vf);
316+
$pref_vf = @unserialize($pref_vf, ['allowed_classes' => [
317+
'IMP_Search_Vfolder',
318+
'IMP_Search_Vfolder_Vinbox',
319+
'IMP_Search_Vfolder_Vtrash',
320+
'IMP_Search_Element_Attachment',
321+
'IMP_Search_Element_Autogenerated',
322+
'IMP_Search_Element_Bulk',
323+
'IMP_Search_Element_Contacts',
324+
'IMP_Search_Element_Daterange',
325+
'IMP_Search_Element_Flag',
326+
'IMP_Search_Element_Header',
327+
'IMP_Search_Element_Mailinglist',
328+
'IMP_Search_Element_Or',
329+
'IMP_Search_Element_Personal',
330+
'IMP_Search_Element_Recipient',
331+
'IMP_Search_Element_Size',
332+
'IMP_Search_Element_Text',
333+
'IMP_Search_Element_Within',
334+
]]);
301335
if (is_array($pref_vf)) {
302336
foreach ($pref_vf as $val) {
303337
if ($val instanceof IMP_Search_Vfolder) {

0 commit comments

Comments
 (0)