VYPR
Medium severityNVD Advisory· Published Jun 9, 2026· Updated Jun 9, 2026

CVE-2026-47352

CVE-2026-47352

Description

Authenticated backend users were able to retrieve file metadata via several Backend API routes without proper permission checks, allowing access to files outside their permitted file mounts or storages. This issue affects TYPO3 CMS versions before 10.4.57, 11.0.0-11.5.51, 12.0.0-12.4.46, 13.0.0-13.4.31 and 14.0.0-14.3.3.

Affected products

2
  • TYPO3/Typo3references
  • TYPO3/TYPO3 CMSllm-fuzzy
    Range: <10.4.57, 11.0.0-11.5.51, 12.0.0-12.4.46, 13.0.0-13.4.31, 14.0.0-14.3.3

Patches

2
bfe7c354168f

[SECURITY] Check file permissions before showing meta data

https://github.com/TYPO3/typo3Oliver HaderJun 9, 2026via github-commit-search
4 files changed · +26 5
  • typo3/sysext/backend/Classes/Controller/File/ImageProcessController.php+3 0 modified
    @@ -42,6 +42,9 @@ public function process(ServerRequestInterface $request): ResponseInterface
             $processedFileId = (int)($request->getQueryParams()['id'] ?? 0);
             try {
                 $processedFile = $this->imageProcessingService->process($processedFileId);
    +            if (!$processedFile->getOriginalFile()->checkActionPermission('read')) {
    +                return new HtmlResponse('', 403);
    +            }
     
                 return new RedirectResponse(
                     GeneralUtility::locationHeaderUrl($processedFile->getPublicUrl() ?? '', $request)
    
  • typo3/sysext/backend/Classes/Controller/LinkController.php+17 5 modified
    @@ -26,6 +26,7 @@
     use TYPO3\CMS\Core\Messaging\FlashMessage;
     use TYPO3\CMS\Core\Messaging\FlashMessageQueue;
     use TYPO3\CMS\Core\Resource\Exception\InsufficientFileAccessPermissionsException;
    +use TYPO3\CMS\Core\Resource\Exception\InsufficientFolderAccessPermissionsException;
     use TYPO3\CMS\Core\Resource\File;
     use TYPO3\CMS\Core\Resource\Folder;
     use TYPO3\CMS\Core\Resource\ResourceFactory;
    @@ -47,34 +48,45 @@ public function resourceAction(ServerRequestInterface $request): ResponseInterfa
             $identifier = $request->getParsedBody()['identifier'] ?? null;
             $resource = null;
     
    -        if ($identifier) {
    -            $resource = $this->resourceFactory->retrieveFileOrFolderObject($identifier);
    -        }
    -
             try {
    +            if ($identifier) {
    +                $resource = $this->resourceFactory->retrieveFileOrFolderObject($identifier);
    +            }
                 if (!$resource instanceof File && !$resource instanceof Folder) {
                     throw new \InvalidArgumentException('Resource must be a file or a folder', 1679039649);
                 }
                 if ($resource->getStorage()->isFallbackStorage()) {
                     throw new InsufficientFileAccessPermissionsException('You are not allowed to access files outside your storages', 1679039650);
                 }
                 if ($resource instanceof File) {
    +                if (!$resource->checkActionPermission('read')) {
    +                    throw new InsufficientFileAccessPermissionsException('You are not allowed to access this file', 1779001351);
    +                }
                     $parameters = [
                         'type' => LinkService::TYPE_FILE,
                         'file' => $resource,
                     ];
                 }
                 if ($resource instanceof Folder) {
    +                // Note: No explicit `$resource->checkActionPermission('read')` check here, as that would
    +                // be a no-op since `ResourceStorage::getFolder()` calls `assureFolderReadPermission()`
    +                // and throws `InsufficientFolderAccessPermissionsException`
                     $parameters = [
                         'type' => LinkService::TYPE_FOLDER,
                         'folder' => $resource,
                     ];
                 }
                 $link = $this->linkService->asString($parameters);
    +        } catch (InsufficientFileAccessPermissionsException|InsufficientFolderAccessPermissionsException $exception) {
    +            $message = match ($exception->getCode()) {
    +                1679039650 => $this->getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang_resource.xlf:ajax.error.message.resourceOutsideOfStorages'),
    +                default => $this->getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang_resource.xlf:ajax.error.message.resourceNoPermissionRead'),
    +            };
    +
    +            return new JsonResponse($this->getResponseData(false, $message));
             } catch (\Exception $exception) {
                 $message = match ($exception->getCode()) {
                     1679039649 => $this->getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang_resource.xlf:ajax.error.message.resourceNotFileOrFolder'),
    -                1679039650 => $this->getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang_resource.xlf:ajax.error.message.resourceOutsideOfStorages'),
                     default => $exception->getMessage(),
                 };
     
    
  • typo3/sysext/backend/Classes/Controller/Resource/ResourceController.php+3 0 modified
    @@ -65,6 +65,9 @@ public function gatherInformationAction(ServerRequestInterface $request): Respon
             if ($resource === null) {
                 return new JsonResponse(null, 404);
             }
    +        if (!$resource->checkActionPermission('read')) {
    +            return new JsonResponse(null, 403);
    +        }
     
             return new JsonResponse($this->getResourceResponseData($resource));
         }
    
  • typo3/sysext/backend/Resources/Private/Language/locallang_resource.xlf+3 0 modified
    @@ -21,6 +21,9 @@
           <trans-unit id="ajax.error.message.resourceOutsideOfStorages">
             <source>Access to files outside your configured storages is not permitted.</source>
           </trans-unit>
    +      <trans-unit id="ajax.error.message.resourceNoPermissionRead">
    +        <source>Reading this resource is not permitted.</source>
    +      </trans-unit>
           <trans-unit id="ajax.error.message.resourceNoPermissionRename">
             <source>Renaming this resource is not permitted.</source>
           </trans-unit>
    
17a3b7830d59

[SECURITY] Check file permissions before showing meta data

https://github.com/TYPO3/typo3Oliver HaderJun 9, 2026via nvd-ref
3 files changed · +23 5
  • typo3/sysext/backend/Classes/Controller/File/ImageProcessController.php+3 0 modified
    @@ -50,6 +50,9 @@ public function process(ServerRequestInterface $request): ResponseInterface
             $processedFileId = (int)($request->getQueryParams()['id'] ?? 0);
             try {
                 $processedFile = $this->imageProcessingService->process($processedFileId);
    +            if (!$processedFile->getOriginalFile()->checkActionPermission('read')) {
    +                return new HtmlResponse('', 403);
    +            }
     
                 return new RedirectResponse(
                     GeneralUtility::locationHeaderUrl($processedFile->getPublicUrl() ?? '')
    
  • typo3/sysext/backend/Classes/Controller/LinkController.php+17 5 modified
    @@ -26,6 +26,7 @@
     use TYPO3\CMS\Core\Messaging\FlashMessage;
     use TYPO3\CMS\Core\Messaging\FlashMessageQueue;
     use TYPO3\CMS\Core\Resource\Exception\InsufficientFileAccessPermissionsException;
    +use TYPO3\CMS\Core\Resource\Exception\InsufficientFolderAccessPermissionsException;
     use TYPO3\CMS\Core\Resource\File;
     use TYPO3\CMS\Core\Resource\Folder;
     use TYPO3\CMS\Core\Resource\ResourceFactory;
    @@ -47,34 +48,45 @@ public function resourceAction(ServerRequestInterface $request): ResponseInterfa
             $identifier = $request->getParsedBody()['identifier'] ?? null;
             $resource = null;
     
    -        if ($identifier) {
    -            $resource = $this->resourceFactory->retrieveFileOrFolderObject($identifier);
    -        }
    -
             try {
    +            if ($identifier) {
    +                $resource = $this->resourceFactory->retrieveFileOrFolderObject($identifier);
    +            }
                 if (!$resource instanceof File && !$resource instanceof Folder) {
                     throw new \InvalidArgumentException('Resource must be a file or a folder', 1679039649);
                 }
                 if ($resource->getStorage()->isFallbackStorage()) {
                     throw new InsufficientFileAccessPermissionsException('You are not allowed to access files outside your storages', 1679039650);
                 }
                 if ($resource instanceof File) {
    +                if (!$resource->checkActionPermission('read')) {
    +                    throw new InsufficientFileAccessPermissionsException('You are not allowed to access this file', 1779001351);
    +                }
                     $parameters = [
                         'type' => LinkService::TYPE_FILE,
                         'file' => $resource,
                     ];
                 }
                 if ($resource instanceof Folder) {
    +                // Note: No explicit `$resource->checkActionPermission('read')` check here, as that would
    +                // be a no-op since `ResourceStorage::getFolder()` calls `assureFolderReadPermission()`
    +                // and throws `InsufficientFolderAccessPermissionsException`
                     $parameters = [
                         'type' => LinkService::TYPE_FOLDER,
                         'folder' => $resource,
                     ];
                 }
                 $link = $this->linkService->asString($parameters);
    +        } catch (InsufficientFileAccessPermissionsException|InsufficientFolderAccessPermissionsException $exception) {
    +            $message = match ($exception->getCode()) {
    +                1679039650 => $this->getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang_resource.xlf:ajax.error.message.resourceOutsideOfStorages'),
    +                default => $this->getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang_resource.xlf:ajax.error.message.resourceNoPermissionRead'),
    +            };
    +
    +            return new JsonResponse($this->getResponseData(false, $message));
             } catch (\Exception $exception) {
                 $message = match ($exception->getCode()) {
                     1679039649 => $this->getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang_resource.xlf:ajax.error.message.resourceNotFileOrFolder'),
    -                1679039650 => $this->getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang_resource.xlf:ajax.error.message.resourceOutsideOfStorages'),
                     default => $exception->getMessage(),
                 };
     
    
  • typo3/sysext/backend/Resources/Private/Language/locallang_resource.xlf+3 0 modified
    @@ -19,6 +19,9 @@
     			<trans-unit id="ajax.error.message.resourceOutsideOfStorages">
     				<source>Access to files outside your configured storages is not permitted.</source>
     			</trans-unit>
    +			<trans-unit id="ajax.error.message.resourceNoPermissionRead">
    +				<source>Reading this resource is not permitted.</source>
    +			</trans-unit>
     			<trans-unit id="ajax.error.message.resourceNoPermissionRename">
     				<source>Renaming this resource is not permitted.</source>
     			</trans-unit>
    

Vulnerability mechanics

Root cause

"Backend API routes did not properly check file permissions before retrieving file metadata."

Attack vector

Authenticated backend users could exploit this vulnerability by making requests to specific Backend API routes that retrieve file metadata. These routes lacked sufficient permission checks, allowing users to access metadata for files outside of their permitted file mounts or storages. The vulnerability was present in multiple versions of TYPO3 CMS.

Affected code

The vulnerability is located in the `resourceAction` method within the TYPO3 backend. The affected code paths are where file and folder objects are retrieved using `resourceFactory->retrieveFileOrFolderObject($identifier)` without adequate permission validation before proceeding to access their metadata [ref_id=1, ref_id=2].

What the fix does

The patch introduces checks for file and folder read permissions before retrieving resource metadata. Specifically, it adds calls to `checkActionPermission('read')` for files and ensures folder read permissions are asserted for folders. This prevents unauthorized access to file metadata by ensuring that only users with appropriate permissions can retrieve the information, thereby closing the vulnerability [patch_id=5349014, patch_id=5349013].

Preconditions

  • authThe attacker must be an authenticated backend user.

Generated on Jun 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

3

News mentions

1