Information Disclosure via File Abstraction Layer
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.
| Package | Affected versions | Patched versions |
|---|---|---|
typo3/cms-corePackagist | >= 9.0.0, < 12.4.37 | 12.4.37 |
typo3/cms-corePackagist | >= 10.0.0, < 12.4.37 | 12.4.37 |
typo3/cms-corePackagist | >= 11.0.0, < 12.4.37 | 12.4.37 |
typo3/cms-corePackagist | >= 12.0.0, < 12.4.37 | 12.4.37 |
typo3/cms-corePackagist | >= 13.0.0, < 13.4.18 | 13.4.18 |
Affected products
2- TYPO3/TYPO3 CMSv5Range: 9.0.0
Patches
1e1e4380a2d8e[SECURITY] Prevent information disclosure via filesystem E_WARNING errors
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- github.com/advisories/GHSA-cvm2-5f78-g9m8ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-59016ghsaADVISORY
- typo3.org/security/advisory/typo3-core-sa-2025-020ghsavendor-advisoryWEB
- github.com/TYPO3-CMS/core/commit/e1e4380a2d8e72228c597403f0463c21d6e1b8d9ghsaWEB
News mentions
0No linked articles in our index yet.