[SECURITY] Add possibility to en-/disable file permission checks 02/23602/2
authorHelmut Hummel <helmut.hummel@typo3.org>
Wed, 4 Sep 2013 11:23:15 +0000 (13:23 +0200)
committerOliver Hader <oliver.hader@typo3.org>
Wed, 4 Sep 2013 11:23:19 +0000 (13:23 +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: I0f0288d52ca769acbf5d0cc06cdd896467b24fdf
Security-Commit: 49092a77f9e4f391aaf94d30501d4a2c47f60a88
Security-Bulletin: TYPO3-CORE-SA-2013-003
Reviewed-on: https://review.typo3.org/23602
Reviewed-by: Oliver Hader
Tested-by: Oliver Hader
typo3/sysext/core/Classes/Resource/ResourceStorage.php

index 33b96df..940e728 100644 (file)
@@ -122,6 +122,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
         *
         * @var array
@@ -500,25 +510,25 @@ 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;
                                }
                        }
                }
@@ -526,6 +536,13 @@ class ResourceStorage {
        }
 
        /**
+        * @param $evaluatePermissions
+        */
+       public function setEvaluatePermissions($evaluatePermissions) {
+               $this->evaluatePermissions = (boolean) $evaluatePermissions;
+       }
+
+       /**
         * Sets the user permissions of the storage
         *
         * @param array $userPermissions
@@ -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;
@@ -632,7 +647,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;
@@ -669,6 +684,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);