VYPR
Moderate severityNVD Advisory· Published Sep 9, 2025· Updated Sep 9, 2025

Information Disclosure via File Abstraction Layer

CVE-2025-59016

Description

Error messages containing sensitive information in the File Abstraction Layer in TYPO3 CMS versions 9.0.0-9.5.54, 10.0.0-10.4.53, 11.0.0-11.5.47, 12.0.0-12.4.36, and 13.0.0-13.4.17 allow backend users to disclose full file paths via failed low-level file-system operations.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

TYPO3 CMS File Abstraction Layer discloses full file paths to backend users via error messages from failed low-level file-system operations.

Vulnerability

Description

CVE-2025-59016 is an information disclosure vulnerability in the File Abstraction Layer (ext:core) of TYPO3 CMS, affecting versions 9.0.0 through 13.4.17. The root cause is that PHP functions such as move_uploaded_file(), rename(), and copy() are called without the error suppression operator (@). When these low-level file-system operations fail, PHP emits E_WARNING messages that include the full absolute path of the affected file or directory, which are then exposed to the user [1][4].

Exploitation

Exploitation requires a valid backend user account. An attacker with backend access can trigger failed file operations (e.g., by attempting to move, rename, or copy files to invalid or permission-restricted locations) through the File Abstraction Layer. The resulting error messages reveal the full server-side file path, which isclosure, aiding further attacks [2][4].

Impact

A successful attack allows ackend user can obtain sensitive information about the server's file system layout, such as absolute paths to files and directories. This information can be used to plan more targeted attacks, such as path traversal or inclusion of specific files, increasing the risk of further compromise [4].

Mitigation

The vulnerability is fixed in TYPO3 versions 9.5.55 ELTS, 10.4.54 ELTS, 11.5.48 ELTS, 12.4.37 LTS, and 13.4.18 LTS. The fix adds the @ operator to suppress PHP warnings before the error-checking logic [1][4]. Users should update immediately. No workaround is mentioned; the advisory recommends following the TYPO3 Security Guide [4].

AI Insight generated on May 19, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
typo3/cms-corePackagist
>= 9.0.0, < 12.4.3712.4.37
typo3/cms-corePackagist
>= 10.0.0, < 12.4.3712.4.37
typo3/cms-corePackagist
>= 11.0.0, < 12.4.3712.4.37
typo3/cms-corePackagist
>= 12.0.0, < 12.4.3712.4.37
typo3/cms-corePackagist
>= 13.0.0, < 13.4.1813.4.18

Affected products

2
  • TYPO3/Typo3llm-fuzzy
    Range: 9.0.0-9.5.54; 10.0.0-10.4.53; 11.0.0-11.5.47; 12.0.0-12.4.36; 13.0.0-13.4.17
  • TYPO3/TYPO3 CMSv5
    Range: 9.0.0

Patches

1
e1e4380a2d8e

[SECURITY] Prevent information disclosure via filesystem E_WARNING errors

https://github.com/TYPO3-CMS/coreAndreas KienastSep 9, 2025via ghsa
1 file changed · +20 20
  • Classes/Resource/Driver/LocalDriver.php+20 20 modified
    @@ -737,12 +737,12 @@ public function addFile(string $localFilePath, string $targetFolderIdentifier, s
     
             if ($removeOriginal) {
                 if (is_uploaded_file($localFilePath)) {
    -                $result = move_uploaded_file($localFilePath, $targetPath);
    +                $result = @move_uploaded_file($localFilePath, $targetPath);
                 } else {
    -                $result = rename($localFilePath, $targetPath);
    +                $result = @rename($localFilePath, $targetPath);
                 }
             } else {
    -            $result = copy($localFilePath, $targetPath);
    +            $result = @copy($localFilePath, $targetPath);
             }
             if ($result === false || !file_exists($targetPath)) {
                 throw new \RuntimeException(
    @@ -826,9 +826,9 @@ public function replaceFile(string $fileIdentifier, string $localFilePath): bool
         {
             $filePath = $this->getAbsolutePath($fileIdentifier);
             if (is_uploaded_file($localFilePath)) {
    -            $result = move_uploaded_file($localFilePath, $filePath);
    +            $result = @move_uploaded_file($localFilePath, $filePath);
             } else {
    -            $result = rename($localFilePath, $filePath);
    +            $result = @rename($localFilePath, $filePath);
             }
             GeneralUtility::fixPermissions($filePath);
             if ($result === false) {
    @@ -854,7 +854,7 @@ public function copyFileWithinStorage(string $fileIdentifier, string $targetFold
             $newIdentifier = $this->canonicalizeAndCheckFileIdentifier($newIdentifier);
     
             $absoluteFilePath = $this->getAbsolutePath($newIdentifier);
    -        copy($sourcePath, $absoluteFilePath);
    +        @copy($sourcePath, $absoluteFilePath);
             GeneralUtility::fixPermissions($absoluteFilePath);
             return $newIdentifier;
         }
    @@ -874,7 +874,7 @@ public function moveFileWithinStorage(string $fileIdentifier, string $targetFold
             $sourcePath = $this->getAbsolutePath($fileIdentifier);
             $targetIdentifier = $targetFolderIdentifier . '/' . $newFileName;
             $targetIdentifier = $this->canonicalizeAndCheckFileIdentifier($targetIdentifier);
    -        $result = rename($sourcePath, $this->getAbsolutePath($targetIdentifier));
    +        $result = @rename($sourcePath, $this->getAbsolutePath($targetIdentifier));
             if ($result === false) {
                 throw new \RuntimeException('Moving file ' . $sourcePath . ' to ' . $targetIdentifier . ' failed.', 1315314712);
             }
    @@ -888,14 +888,14 @@ protected function copyFileToTemporaryPath(string $fileIdentifier): string
         {
             $sourcePath = $this->getAbsolutePath($fileIdentifier);
             $temporaryPath = $this->getTemporaryPathForFile($fileIdentifier);
    -        $result = copy($sourcePath, $temporaryPath);
    -        touch($temporaryPath, (int)filemtime($sourcePath));
    +        $result = @copy($sourcePath, $temporaryPath);
             if ($result === false) {
                 throw new \RuntimeException(
                     'Copying file "' . $fileIdentifier . '" to temporary path "' . $temporaryPath . '" failed.',
                     1320577649
                 );
             }
    +        @touch($temporaryPath, (int)filemtime($sourcePath));
             return $temporaryPath;
         }
     
    @@ -910,11 +910,11 @@ protected function recycleFileOrFolder(string $filePath, string $recycleDirector
                 $timeStamp = \DateTimeImmutable::createFromFormat('U.u', (string)microtime(true))->format('YmdHisu');
                 $destinationFile = $recycleDirectory . '/' . $timeStamp . '_' . PathUtility::basename($filePath);
             }
    -        $result = rename($filePath, $destinationFile);
    +        $result = @rename($filePath, $destinationFile);
             // Update the mtime for the file, so the recycler garbage collection task knows which files to delete
             // Using ctime() is not possible there since this is not supported on Windows
             if ($result) {
    -            touch($destinationFile);
    +            @touch($destinationFile);
             }
             return $result;
         }
    @@ -965,7 +965,7 @@ public function moveFolderWithinStorage(string $sourceFolderIdentifier, string $
             $targetPath = $this->getAbsolutePath($relativeTargetPath);
             // get all files and folders we are going to move, to have a map for updating later.
             $filesAndFolders = $this->retrieveFileAndFoldersInPath($sourcePath, true);
    -        $result = rename($sourcePath, $targetPath);
    +        $result = @rename($sourcePath, $targetPath);
             if ($result === false) {
                 throw new \RuntimeException('Moving folder ' . $sourcePath . ' to ' . $targetPath . ' failed.', 1320711817);
             }
    @@ -1007,7 +1007,7 @@ public function copyFolderWithinStorage(string $sourceFolderIdentifier, string $
                 } elseif ($current->isFile()) {
                     $copySourcePath = $sourceFolderPath . '/' . $itemSubPath;
                     $copyTargetPath = $targetFolderPath . '/' . $itemSubPath;
    -                $result = copy($copySourcePath, $copyTargetPath);
    +                $result = @copy($copySourcePath, $copyTargetPath);
                     if ($result === false) {
                         // rollback
                         GeneralUtility::rmdir($targetFolderIdentifier, true);
    @@ -1045,7 +1045,7 @@ public function renameFile(string $fileIdentifier, string $newName): string
             }
             $sourcePath = $this->getAbsolutePath($fileIdentifier);
             $targetPath = $this->getAbsolutePath($newIdentifier);
    -        $result = rename($sourcePath, $targetPath);
    +        $result = @rename($sourcePath, $targetPath);
             if ($result === false) {
                 throw new \RuntimeException('Renaming file ' . $sourcePath . ' to ' . $targetPath . ' failed.', 1320375115);
             }
    @@ -1072,15 +1072,15 @@ public function renameFolder(string $folderIdentifier, string $newName): array
             $targetPath = $this->getAbsolutePath($newIdentifier);
             // get all files and folders we are going to move, to have a map for updating later.
             $filesAndFolders = $this->retrieveFileAndFoldersInPath($sourcePath, true);
    -        $result = rename($sourcePath, $targetPath);
    +        $result = @rename($sourcePath, $targetPath);
             if ($result === false) {
                 throw new \RuntimeException(sprintf('Renaming folder "%1$s" to "%2$s" failed."', $sourcePath, $targetPath), 1320375116);
             }
             try {
                 // Create a mapping from old to new identifiers
                 $identifierMap = $this->createIdentifierMap($filesAndFolders, $folderIdentifier, $newIdentifier);
             } catch (\Exception $e) {
    -            rename($targetPath, $sourcePath);
    +            @rename($targetPath, $sourcePath);
                 throw new \RuntimeException(
                     sprintf(
                         'Creating filename mapping after renaming "%1$s" to "%2$s" failed. Reverted rename operation.\\n\\nOriginal error: %3$s"',
    @@ -1104,7 +1104,7 @@ public function renameFolder(string $folderIdentifier, string $newName): array
         public function deleteFile(string $fileIdentifier): bool
         {
             $filePath = $this->getAbsolutePath($fileIdentifier);
    -        $result = unlink($filePath);
    +        $result = @unlink($filePath);
     
             if ($result === false) {
                 throw new \RuntimeException('Deletion of file ' . $fileIdentifier . ' failed.', 1320855304);
    @@ -1234,12 +1234,12 @@ public function createFile(string $fileName, string $parentFolderIdentifier): st
                 $parentFolderIdentifier . $fileName
             );
             $absoluteFilePath = $this->getAbsolutePath($fileIdentifier);
    -        $result = touch($absoluteFilePath);
    -        GeneralUtility::fixPermissions($absoluteFilePath);
    -        clearstatcache();
    +        $result = @touch($absoluteFilePath);
             if ($result !== true) {
                 throw new \RuntimeException('Creating file ' . $fileIdentifier . ' failed.', 1320569854);
             }
    +        GeneralUtility::fixPermissions($absoluteFilePath);
    +        clearstatcache();
             return $fileIdentifier;
         }
     
    

Vulnerability mechanics

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

References

4

News mentions

0

No linked articles in our index yet.