]> source.dussan.org Git - nextcloud-server.git/commitdiff
fix: add some recrusive detection/prevention 44321/head
authorRobin Appelman <robin@icewind.nl>
Mon, 21 Aug 2023 17:45:03 +0000 (19:45 +0200)
committerRobin Appelman <robin@icewind.nl>
Tue, 19 Mar 2024 14:02:30 +0000 (15:02 +0100)
Signed-off-by: Robin Appelman <robin@icewind.nl>
apps/files_sharing/lib/SharedStorage.php
lib/private/Files/Storage/Wrapper/Wrapper.php

index c9d8fbffc641d4bf05a44fbf76795ec1adb0b904..ad43e847d37baf2b9ddb08e2df2397401affd7c0 100644 (file)
@@ -44,6 +44,7 @@ use OCP\Files\IHomeStorage;
 use OCP\Files\Node;
 use OC\Files\Storage\FailedStorage;
 use OC\Files\Storage\Wrapper\PermissionsMask;
+use OC\Files\Storage\Wrapper\Wrapper;
 use OC\User\NoUserException;
 use OCA\Files_External\Config\ExternalMountPoint;
 use OCP\Constants;
@@ -98,6 +99,8 @@ class SharedStorage extends \OC\Files\Storage\Wrapper\Jail implements ISharedSto
 
        private string $sourcePath = '';
 
+       private static int $initDepth = 0;
+
        public function __construct($arguments) {
                $this->ownerView = $arguments['ownerView'];
                $this->logger = \OC::$server->getLogger();
@@ -137,8 +140,15 @@ class SharedStorage extends \OC\Files\Storage\Wrapper\Jail implements ISharedSto
                if ($this->initialized) {
                        return;
                }
+
                $this->initialized = true;
+               self::$initDepth++;
+
                try {
+                       if (self::$initDepth > 10) {
+                               throw new \Exception("Maximum share depth reached");
+                       }
+
                        /** @var IRootFolder $rootFolder */
                        $rootFolder = \OC::$server->get(IRootFolder::class);
                        $this->ownerUserFolder = $rootFolder->getUserFolder($this->superShare->getShareOwner());
@@ -151,6 +161,9 @@ class SharedStorage extends \OC\Files\Storage\Wrapper\Jail implements ISharedSto
                                $this->cache = new FailedCache();
                                $this->rootPath = '';
                        } else {
+                               if ($this->nonMaskedStorage instanceof Wrapper && $this->nonMaskedStorage->isWrapperOf($this)) {
+                                       throw new \Exception('recursive share detected');
+                               }
                                $this->nonMaskedStorage = $ownerNode->getStorage();
                                $this->sourcePath = $ownerNode->getPath();
                                $this->rootPath = $ownerNode->getInternalPath();
@@ -179,6 +192,7 @@ class SharedStorage extends \OC\Files\Storage\Wrapper\Jail implements ISharedSto
                if (!$this->nonMaskedStorage) {
                        $this->nonMaskedStorage = $this->storage;
                }
+               self::$initDepth--;
        }
 
        /**
index 9f5564b449038ee20ce3132d466d9312133d4a46..665914df2a722462c23441984f9c971658d44ea6 100644 (file)
@@ -654,4 +654,15 @@ class Wrapper implements \OC\Files\Storage\Storage, ILockingStorage, IWriteStrea
        public function getDirectoryContent($directory): \Traversable {
                return $this->getWrapperStorage()->getDirectoryContent($directory);
        }
+
+       public function isWrapperOf(IStorage $storage) {
+               $wrapped = $this->getWrapperStorage();
+               if ($wrapped === $storage) {
+                       return true;
+               }
+               if ($wrapped instanceof Wrapper) {
+                       return $wrapped->isWrapperOf($storage);
+               }
+               return false;
+       }
 }