From 669ff56fa1c956d026f2d1b813e21e24396cec52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20Chilliet?= Date: Tue, 9 Dec 2025 16:40:12 +0100 Subject: [PATCH] fix(dav): Use an exhaustive list for allowed serialized classes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is simpler and clearer than trying to guess namespace. Signed-off-by: Côme Chilliet --- apps/dav/lib/DAV/CustomPropertiesBackend.php | 47 ++++++++++++++------ 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/apps/dav/lib/DAV/CustomPropertiesBackend.php b/apps/dav/lib/DAV/CustomPropertiesBackend.php index 8e7d489dad0cc..c95e1ea1a7024 100644 --- a/apps/dav/lib/DAV/CustomPropertiesBackend.php +++ b/apps/dav/lib/DAV/CustomPropertiesBackend.php @@ -113,6 +113,34 @@ class CustomPropertiesBackend implements BackendInterface { '{http://owncloud.org/ns}calendar-enabled' => '1', ]; + /** + * Allowed classes for deserialization + * + * @var class-string[] + */ + private const ALLOWED_SERIALIZED_CLASSES = [ + \Sabre\CalDAV\Xml\Property\AllowedSharingModes::class, + \Sabre\CalDAV\Xml\Property\EmailAddressSet::class, + \Sabre\CalDAV\Xml\Property\Invite::class, + \Sabre\CalDAV\Xml\Property\ScheduleCalendarTransp::class, + \Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet::class, + \Sabre\CalDAV\Xml\Property\SupportedCalendarData::class, + \Sabre\CalDAV\Xml\Property\SupportedCollationSet::class, + \Sabre\CardDAV\Xml\Property\SupportedAddressData::class, + \Sabre\CardDAV\Xml\Property\SupportedCollationSet::class, + \Sabre\DAV\Xml\Property\Complex::class, + \Sabre\DAV\Xml\Property\GetLastModified::class, + \Sabre\DAV\Xml\Property\Href::class, + \Sabre\DAV\Xml\Property\Invite::class, + \Sabre\DAV\Xml\Property\LocalHref::class, + \Sabre\DAV\Xml\Property\LockDiscovery::class, + \Sabre\DAV\Xml\Property\ResourceType::class, + \Sabre\DAV\Xml\Property\ShareAccess::class, + \Sabre\DAV\Xml\Property\SupportedLock::class, + \Sabre\DAV\Xml\Property\SupportedMethodSet::class, + \Sabre\DAV\Xml\Property\SupportedReportSet::class, + ]; + /** * Properties cache */ @@ -620,10 +648,7 @@ private function encodeValueForDatabase(string $path, string $name, mixed $value "Property \"$name\" has an invalid value of type " . gettype($value), ); } else { - if (!str_starts_with($value::class, 'Sabre\\DAV\\Xml\\Property\\') - && !str_starts_with($value::class, 'Sabre\\CalDAV\\Xml\\Property\\') - && !str_starts_with($value::class, 'Sabre\\CardDAV\\Xml\\Property\\') - && !str_starts_with($value::class, 'OCA\\DAV\\')) { + if (!in_array($value::class, self::ALLOWED_SERIALIZED_CLASSES)) { throw new DavException( "Property \"$name\" has an invalid value of class " . $value::class, ); @@ -647,16 +672,10 @@ private function decodeValueFromDatabase(string $value, int $valueType): mixed { case self::PROPERTY_TYPE_HREF: return new Href($value); case self::PROPERTY_TYPE_OBJECT: - if (preg_match('/^a:/', $value)) { - // Array, unserialize only scalar values - return unserialize(str_replace('\x00', chr(0), $value), ['allowed_classes' => false]); - } - if (!preg_match('/^O\:\d+\:\"(OCA\\\\DAV\\\\|Sabre\\\\(Cal|Card)?DAV\\\\Xml\\\\Property\\\\)/', $value)) { - throw new \LogicException('Found an object class serialized in DB that is not allowed'); - } - // some databases can not handel null characters, these are custom encoded during serialization - // this custom encoding needs to be first reversed before unserializing - return unserialize(str_replace('\x00', chr(0), $value)); + return unserialize( + str_replace('\x00', chr(0), $value), + ['allowed_classes' => self::ALLOWED_SERIALIZED_CLASSES] + ); default: return $value; };