[SECURITY] Respect permissions of storages in a file collection 02/53902/2
authorGeorg Ringer <georg.ringer@gmail.com>
Tue, 5 Sep 2017 09:37:22 +0000 (11:37 +0200)
committerOliver Hader <oliver.hader@typo3.org>
Tue, 5 Sep 2017 09:37:24 +0000 (11:37 +0200)
If a user creates a sys_file_collection record, only those
storage records must be shown which are allowed for the
user.

Resolves: #82029
Releases: master, 8.7, 7.6
Security-Commit: 45cdfccd52a224d8128e537214606848c717d8e7
Security-Bulletin: TYPO3-CORE-SA-2017-005
Change-Id: Iee94cd84f07ee0dc0730fe1ce84d228dad2f75a2
Reviewed-on: https://review.typo3.org/53902
Reviewed-by: Oliver Hader <oliver.hader@typo3.org>
Tested-by: Oliver Hader <oliver.hader@typo3.org>
typo3/sysext/backend/Classes/Form/FormDataProvider/AbstractItemProvider.php
typo3/sysext/backend/Classes/Form/FormDataProvider/TcaSelectItems.php
typo3/sysext/core/Classes/Resource/Service/UserFileMountService.php

index 1dc508b..e8a1ae6 100644 (file)
@@ -672,6 +672,40 @@ abstract class AbstractItemProvider
     }
 
     /**
+     * Remove items if sys_file_storage is not allowed for non-admin users.
+     *
+     * Used by TcaSelectItems data providers
+     *
+     * @param array $result Result array
+     * @param string $fieldName Current handle field name
+     * @param array $items Incoming items
+     * @return array Modified item array
+     */
+    protected function removeItemsByUserStorageRestriction(array $result, $fieldName, array $items)
+    {
+        $referencedTableName = $result['processedTca']['columns'][$fieldName]['config']['foreign_table'] ?? null;
+        if ($referencedTableName !== 'sys_file_storage') {
+            return $items;
+        }
+
+        $allowedStorageIds = array_map(
+            function (\TYPO3\CMS\Core\Resource\ResourceStorage $storage) {
+                return $storage->getUid();
+            },
+            $this->getBackendUser()->getFileStorages()
+        );
+
+        return array_filter(
+            $items,
+            function (array $item) use ($allowedStorageIds) {
+                $itemValue = $item[1] ?? null;
+                return empty($itemValue)
+                    || in_array((int)$itemValue, $allowedStorageIds, true);
+            }
+        );
+    }
+
+    /**
      * Returns an array with the exclude fields as defined in TCA and FlexForms
      * Used for listing the exclude fields in be_groups forms.
      *
index 4193b4d..b443521 100644 (file)
@@ -54,8 +54,11 @@ class TcaSelectItems extends AbstractItemProvider implements FormDataProviderInt
             $staticItems = $fieldConfig['config']['items'];
 
             $fieldConfig['config']['items'] = $this->addItemsFromForeignTable($result, $fieldName, $fieldConfig['config']['items']);
-            $dynamicItems = array_diff_key($fieldConfig['config']['items'], $staticItems);
+            // removing items before $dynamicItems and $removedItems have been built results in having them
+            // not populated to the dynamic database row and displayed as "invalid value" in the forms view
+            $fieldConfig['config']['items'] = $this->removeItemsByUserStorageRestriction($result, $fieldName, $fieldConfig['config']['items']);
 
+            $dynamicItems = array_diff_key($fieldConfig['config']['items'], $staticItems);
             $removedItems = $fieldConfig['config']['items'];
 
             $fieldConfig['config']['items'] = $this->removeItemsByKeepItemsPageTsConfig($result, $fieldName, $fieldConfig['config']['items']);
index 240805d..686eec1 100644 (file)
@@ -14,6 +14,7 @@ namespace TYPO3\CMS\Core\Resource\Service;
  * The TYPO3 project - inspiring people to share!
  */
 
+use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Messaging\FlashMessage;
 use TYPO3\CMS\Core\Messaging\FlashMessageService;
 use TYPO3\CMS\Core\Resource\Exception\InsufficientFolderReadPermissionsException;
@@ -36,17 +37,22 @@ class UserFileMountService
      * of a selected mount
      *
      * @param array $PA the array with additional configuration options.
-     * @return string The HTML code for the TCEform field
      */
     public function renderTceformsSelectDropdown(&$PA)
     {
+        $allowedStorageIds = array_map(
+            function(\TYPO3\CMS\Core\Resource\ResourceStorage $storage) {
+                return $storage->getUid();
+            },
+            $this->getBackendUserAuthentication()->getFileStorages()
+        );
         // If working for sys_filemounts table
         $storageUid = (int)$PA['row']['base'][0];
         if (!$storageUid) {
             // If working for sys_file_collection table
             $storageUid = (int)$PA['row']['storage'][0];
         }
-        if ($storageUid > 0) {
+        if ($storageUid > 0 && in_array($storageUid, $allowedStorageIds, true)) {
             /** @var $storageRepository StorageRepository */
             $storageRepository = GeneralUtility::makeInstance(StorageRepository::class);
             /** @var $storage \TYPO3\CMS\Core\Resource\ResourceStorage */
@@ -127,4 +133,14 @@ class UserFileMountService
         }
         return $allFolderItems;
     }
+
+    /**
+     * Returns the BE USER Object
+     *
+     * @return BackendUserAuthentication
+     */
+    protected function getBackendUserAuthentication(): BackendUserAuthentication
+    {
+        return $GLOBALS['BE_USER'];
+    }
 }