[SECURITY] Add possibility to en-/disable file permission checks 96/23596/2
authorHelmut Hummel <helmut.hummel@typo3.org>
Wed, 4 Sep 2013 11:13:56 +0000 (13:13 +0200)
committerOliver Hader <oliver.hader@typo3.org>
Wed, 4 Sep 2013 11:14:01 +0000 (13:14 +0200)
For admins and for front end request, we must be able
to deactivate permission checks completely, while
it must be possible to restrict backend users
to not have any file permissions thus, not be able to
see/change any file.

Fixes: #51326
Releases: 6.2, 6.1, 6.0

Change-Id: I0b2ba16562d412e4a3bb523a54f7de317ea25c25
Security-Commit: eceac26733d6dff1826b149494532fb321274611
Security-Bulletin: TYPO3-CORE-SA-2013-003
Reviewed-on: https://review.typo3.org/23596
Reviewed-by: Oliver Hader
Tested-by: Oliver Hader
typo3/sysext/core/Classes/Resource/ResourceStorage.php

index 5cf4c52..87b842d 100644 (file)
@@ -121,6 +121,16 @@ class ResourceStorage {
         */
        protected $fileProcessingService;
 
+       /**
+        * Whether to check if file or folder is in user mounts
+        * and the action is allowed for a user
+        * Default is FALSE so that resources are accessible for
+        * front end rendering or admins.
+        *
+        * @var boolean
+        */
+       protected $evaluatePermissions = FALSE;
+
        /**
         * User filemounts, added as an array, and used as filters
         *
@@ -500,31 +510,38 @@ class ResourceStorage {
         * @return boolean
         */
        public function isWithinFileMountBoundaries($subject) {
-               $isWithinFilemount = TRUE;
-               if (is_array($this->fileMounts) && count($this->fileMounts)) {
-                       $isWithinFilemount = FALSE;
-                       if (!$subject) {
-                               $subject = $this->getRootLevelFolder();
-                       }
-                       $identifier = $subject->getIdentifier();
+               if (!$this->evaluatePermissions) {
+                       return TRUE;
+               }
+               $isWithinFilemount = FALSE;
+               if (!$subject) {
+                       $subject = $this->getRootLevelFolder();
+               }
+               $identifier = $subject->getIdentifier();
 
-                       // Allow access to processing folder
-                       if ($this->driver->isWithin($this->getProcessingFolder(), $identifier)) {
-                               $isWithinFilemount = TRUE;
-                       } else {
-                               // Check if the identifier of the subject is within at
-                               // least one of the file mounts
-                               foreach ($this->fileMounts as $fileMount) {
-                                       if ($this->driver->isWithin($fileMount['folder'], $identifier)) {
-                                               $isWithinFilemount = TRUE;
-                                               break;
-                                       }
+               // Allow access to processing folder
+               if ($this->driver->isWithin($this->getProcessingFolder(), $identifier)) {
+                       $isWithinFilemount = TRUE;
+               } else {
+                       // Check if the identifier of the subject is within at
+                       // least one of the file mounts
+                       foreach ($this->fileMounts as $fileMount) {
+                               if ($this->driver->isWithin($fileMount['folder'], $identifier)) {
+                                       $isWithinFilemount = TRUE;
+                                       break;
                                }
                        }
                }
                return $isWithinFilemount;
        }
 
+       /**
+        * @param $evaluatePermissions
+        */
+       public function setEvaluatePermissions($evaluatePermissions) {
+               $this->evaluatePermissions = (boolean) $evaluatePermissions;
+       }
+
        /**
         * Sets the user permissions of the storage
         *
@@ -544,18 +561,16 @@ class ResourceStorage {
         * @return      bool
         */
        public function checkUserActionPermission($action, $type) {
-               // TODO decide if we should return TRUE if no permissions are set
-               if (!empty($this->userPermissions)) {
-                       $action = strtolower($action);
-                       $type = ucfirst(strtolower($type));
-                       if ($this->userPermissions[$action . $type] == 0) {
-                               return FALSE;
-                       } else {
-                               return TRUE;
-                       }
+               if (!$this->evaluatePermissions) {
+                       return TRUE;
                }
-               // TODO should the default be really TRUE?
-               return TRUE;
+
+               $allow = FALSE;
+               if (!empty($this->userPermissions[strtolower($action) . ucfirst(strtolower($type))])) {
+                       $allow = TRUE;
+               }
+
+               return $allow;
        }
 
        /**
@@ -583,7 +598,7 @@ class ResourceStorage {
                }
                // Check 3: Does the user have the right to perform the action?
                // (= is he within the file mount borders)
-               if (!$isProcessedFile && is_array($this->fileMounts) && count($this->fileMounts) && !$this->isWithinFileMountBoundaries($file)) {
+               if (!$isProcessedFile && !$this->isWithinFileMountBoundaries($file)) {
                        return FALSE;
                }
                $isReadCheck = FALSE;
@@ -640,7 +655,7 @@ class ResourceStorage {
 
                // Check 2: Does the user has the right to perform the action?
                // (= is he within the file mount borders)
-               if (is_array($this->fileMounts) && count($this->fileMounts) && !$this->isWithinFileMountBoundaries($folder)) {
+               if (!$this->isWithinFileMountBoundaries($folder)) {
                        return FALSE;
                }
                $isReadCheck = FALSE;
@@ -677,6 +692,9 @@ class ResourceStorage {
         * @return boolean TRUE if extension/filename is allowed
         */
        protected function checkFileExtensionPermission($fileName) {
+               if (!$this->evaluatePermissions) {
+                       return TRUE;
+               }
                $isAllowed = GeneralUtility::verifyFilenameAgainstDenyPattern($fileName);
                if ($isAllowed) {
                        $fileInfo = GeneralUtility::split_fileref($fileName);