From f69cac4936d132cb3e417d500abbf1fdc55535f7 Mon Sep 17 00:00:00 2001 From: Andreas Haerter Date: Mon, 19 Oct 2026 00:25:23 +0200 Subject: [PATCH] Return 403 instead of 500 for a vCard read with only read-free-busy A user who holds only read-free-busy on another user's address book got HTTP 500 for a GET or HEAD of one of its vCards. caldav-GET.php builds an obfuscated "Busy" copy for readers without DAV::read, but a vCard has no calendar component, so obfuscated_event() received null and called GetType() on it. Free/busy access has nothing to show for a vCard, so refuse it with 403 Forbidden, as PROPFIND of the same address book already does. Closes #343 --- inc/caldav-GET.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/inc/caldav-GET.php b/inc/caldav-GET.php index 0a67a705..371fac30 100644 --- a/inc/caldav-GET.php +++ b/inc/caldav-GET.php @@ -54,6 +54,10 @@ if ( $dav_resource->HavePrivilegeTo('all', false) || $session->user_no == $resou else if ( $resource->class != 'PRIVATE' ) { $allowed = true; // but we may well obfuscate it below if ( ! $dav_resource->HavePrivilegeTo('DAV::read') || ( $resource->class == 'CONFIDENTIAL' && ! $request->HavePrivilegeTo('DAV::write-content') ) ) { + if ( $resource->caldav_type == 'VCARD' ) { + // Free/busy access covers calendar data only; a vCard has no busy time to show. + $request->DoResponse( 403, translate("Forbidden") ); + } $ical = new iCalComponent( $resource->caldav_data ); $comps = $ical->GetComponents('VTIMEZONE',false); $confidential = obfuscated_event($comps[0]);