CVE-2024-36070: Insufficient Information (NVD-CWE-noinfo)
value: tine before 2023.11.8, when an LDAP backend is used, allows anonymous remote attackers to obtain sensitive authentication information via setup.php because of getRegistryData in Setup/Frontend/Json.php. (An update is also available for the 2022.11 series.)
CWE description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
Published: 2024-05-19T19:15Z
Repository: https://github.com/tine-groupware/tine
Language: PHP
Files changed: tine20/Setup/Frontend/Json.php
Commit date: 2024-04-09 16:21:19 +0200
Commit message: fix(Setup/Frontend/Json): don't show auth data in anonymous call

thx @Christian Pöschl of usd AG

see usd-2024-0002 | Tine 2023.11.2 - Password Leakage

Diff: diff --git a/tine20/Setup/Frontend/Json.php b/tine20/Setup/Frontend/Json.php
index ef18952d88..9a8c15423a 100644
--- a/tine20/Setup/Frontend/Json.php
+++ b/tine20/Setup/Frontend/Json.php
@@ -267,18 +267,15 @@ class Setup_Frontend_Json extends Tinebase_Frontend_Abstract
         );
     }
     
     /**
      * Returns registry data of setup
-     * .
-     * @see Tinebase_Application_Json_Abstract
-     * 
-     * @return mixed array 'variable name' => 'data'
-     * 
-     * @todo add 'titlePostfix'    => Tinebase_Config::getInstance()->getConfig(Tinebase_Config::PAGETITLEPOSTFIX, NULL, '')->value here?
+     *
+     * @return array
+     * @throws Tinebase_Exception_InvalidArgument
      */
-    public function getRegistryData()
+    public function getRegistryData(): array
     {
         // anonymous registry
         $registryData =  array(
             'configExists'     => Setup_Core::configFileExists(),
             'version'          => array(
@@ -287,22 +284,27 @@ class Setup_Frontend_Json extends Tinebase_Frontend_Abstract
                 'packageString' => TINE20SETUP_PACKAGESTRING,
                 'releaseTime'   => TINE20SETUP_RELEASETIME,
                 // NOTE: if assetHash is not available we have a serious problem -  please don't generate one!
                 'assetHash'     => Tinebase_Frontend_Http_SinglePageApplication::getAssetHash(),
             ),
-            'authenticationData'   => $this->loadAuthenticationData(),
         );
         
-        // authenticated or non existent config
+        // authenticated or non-existent config
         if (! Setup_Core::configFileExists() || Setup_Core::isRegistered(Setup_Core::USER)) {
             $registryData = array_merge($registryData, $this->checkConfig());
             $registryData = array_merge($registryData, array(
+                'authenticationData'   => Setup_Core::isRegistered(Setup_Core::USER)
+                    ? $this->loadAuthenticationData() : [],
                 'rights'               => ['admin'],
-                'acceptedTermsVersion' => (! empty($registryData['checkDB']) && $this->_controller->isInstalled('Tinebase')) ? Setup_Controller::getInstance()->getAcceptedTerms() : 0,
+                'acceptedTermsVersion' => (! empty($registryData['checkDB']) &&
+                    $this->_controller->isInstalled(''))
+                    ? Setup_Controller::getInstance()->getAcceptedTerms() : 0,
                 'setupChecks'          => $this->envCheck(),
                 'configData'           => $this->loadConfig(),
-                'emailData'            => (! empty($registryData['checkDB']) && $this->_controller->isInstalled('Tinebase')) ? $this->getEmailConfig() : array(),
+                'emailData'            => (! empty($registryData['checkDB'])
+                    && $this->_controller->isInstalled() && Setup_Core::isRegistered(Setup_Core::USER))
+                        ? $this->getEmailConfig() : array(),
             ));
         }
         
         // if setup user is logged in
         if (Setup_Core::isRegistered(Setup_Core::USER)) {
@@ -311,36 +313,36 @@ class Setup_Frontend_Json extends Tinebase_Frontend_Abstract
             );
         }
         
         return $registryData;
     }
-    
+
     /**
      * Returns registry data of all applications current user has access to
      * @see Tinebase_Application_Json_Abstract
-     * 
+     *
      * @return mixed array 'variable name' => 'data'
      *
      * TODO DRY: most of this already is part of Tinebase_Frontend_Json::_getAnonymousRegistryData
      */
     public function getAllRegistryData()
     {
         // clear cache to make sure we have current data...
         Setup_Controller::getInstance()->clearCache();
 
         $registryData['Setup'] = $this->getRegistryData();
-        
+
         // setup also need some core tinebase regdata
         $locale = Tinebase_Core::get('locale');
         $symbols = Zend_Locale::getTranslationList('symbols', $locale);
 
         $registryData['Tinebase'] = array(
             'serviceMap'       => Setup_Frontend_Http::getServiceMap(),
             'timeZone'         => Setup_Core::getUserTimezone(),
             'jsonKey'          => Setup_Core::get('jsonKey'),
             'locale'           => array(
-                'locale'   => $locale->toString(), 
+                'locale'   => $locale->toString(),
                 'language' => Zend_Locale::getTranslation($locale->getLanguage(), 'language', $locale),
                 'region'   => Zend_Locale::getTranslation($locale->getRegion(), 'country', $locale),
             ),
             'version'          => array(
                 'buildType'     => TINE20_BUILDTYPE,

Vulnerable code:      * .
     * @see Tinebase_Application_Json_Abstract
     * 
     * @return mixed array 'variable name' => 'data'
     * 
     * @todo add 'titlePostfix'    => Tinebase_Config::getInstance()->getConfig(Tinebase_Config::PAGETITLEPOSTFIX, NULL, '')->value here?
    public function getRegistryData()
            'authenticationData'   => $this->loadAuthenticationData(),
        // authenticated or non existent config
                'acceptedTermsVersion' => (! empty($registryData['checkDB']) && $this->_controller->isInstalled('Tinebase')) ? Setup_Controller::getInstance()->getAcceptedTerms() : 0,
                'emailData'            => (! empty($registryData['checkDB']) && $this->_controller->isInstalled('Tinebase')) ? $this->getEmailConfig() : array(),
    
     * 
        
                'locale'   => $locale->toString(), 
Fixed code:      *
     * @return array
     * @throws Tinebase_Exception_InvalidArgument
    public function getRegistryData(): array
        // authenticated or non-existent config
                'authenticationData'   => Setup_Core::isRegistered(Setup_Core::USER)
                    ? $this->loadAuthenticationData() : [],
                'acceptedTermsVersion' => (! empty($registryData['checkDB']) &&
                    $this->_controller->isInstalled(''))
                    ? Setup_Controller::getInstance()->getAcceptedTerms() : 0,
                'emailData'            => (! empty($registryData['checkDB'])
                    && $this->_controller->isInstalled() && Setup_Core::isRegistered(Setup_Core::USER))
                        ? $this->getEmailConfig() : array(),

     *

                'locale'   => $locale->toString(),