‪TYPO3CMS  11.5
FilePathSanitizer.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
27 
39 {
47  protected ‪$allowedPaths = [];
48 
52  public function ‪__construct()
53  {
54  $this->allowedPaths = [
55  '_assets/',
56  ‪$GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'],
57  'uploads/',
58  'typo3temp/',
62  ];
63  if (!empty(‪$GLOBALS['TYPO3_CONF_VARS']['FE']['addAllowedPaths'])) {
64  $paths = ‪GeneralUtility::trimExplode(',', ‪$GLOBALS['TYPO3_CONF_VARS']['FE']['addAllowedPaths'], true);
65  foreach ($paths as $path) {
66  if (is_string($path)) {
67  $this->allowedPaths[] = $path;
68  }
69  }
70  }
71  }
72 
80  public function ‪sanitize(string $originalFileName, ?bool $allowExtensionPath = null): string
81  {
82  if ($allowExtensionPath === false) {
83  throw new \BadMethodCallException('$allowAbsolutePaths must be either omitted or set to true', 1633671654);
84  }
85  $file = trim($originalFileName);
86  if (empty($file)) {
87  throw new ‪InvalidFileNameException('Empty file name given', 1530169746);
88  }
89  if (str_contains($file, '../')) {
90  throw new ‪InvalidPathException('File path "' . $file . '" contains illegal string "../"', 1530169814);
91  }
92  // if this is an URL, it can be returned directly
93  $urlScheme = parse_url($file, PHP_URL_SCHEME);
94  if ($urlScheme === 'https' || $urlScheme === 'http' || is_file(‪Environment::getPublicPath() . '/' . $file)) {
95  return $file;
96  }
97 
98  // this call also resolves EXT:myext/ files
99  $absolutePath = GeneralUtility::getFileAbsFileName($file);
100  if (!$absolutePath || is_dir($absolutePath)) {
101  throw new ‪FileDoesNotExistException('File "' . $file . '" was not found', 1530169845);
102  }
103 
104  $isExtensionPath = ‪PathUtility::isExtensionPath($file);
105  if ($allowExtensionPath && $isExtensionPath) {
106  return $file;
107  }
108  $relativePath = $this->‪makeRelative($absolutePath, $file, $isExtensionPath);
109 
110  // Check if the found file is in the allowed paths
111  foreach ($this->allowedPaths as $allowedPath) {
112  if (strpos($relativePath, $allowedPath) === 0) {
113  return $relativePath;
114  }
115  }
116  throw new ‪InvalidFileException('"' . $relativePath . '" is not located in the allowed paths', 1530169955);
117  }
118 
119  private function ‪makeRelative(string $absoluteFilePath, string $originalFilePath, bool $isExtensionPath): string
120  {
121  if ($isExtensionPath) {
122  return ‪PathUtility::getPublicResourceWebPath($originalFilePath, false);
123  }
124 
125  if (!str_starts_with($absoluteFilePath, ‪Environment::getPublicPath())) {
126  throw new ‪InvalidFileException('"' . $originalFilePath . '" is expected to be in public directory, but is not', 1633674049);
127  }
128 
129  return ‪PathUtility::stripPathSitePrefix($absoluteFilePath);
130  }
131 }
‪TYPO3\CMS\Core\Utility\GeneralUtility\trimExplode
‪static list< string > trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
Definition: GeneralUtility.php:999
‪TYPO3\CMS\Core\Utility\PathUtility
Definition: PathUtility.php:25
‪TYPO3\CMS\Core\Core\Environment\getPublicPath
‪static string getPublicPath()
Definition: Environment.php:206
‪TYPO3\CMS\Frontend\Resource
Definition: FileCollector.php:16
‪TYPO3\CMS\Core\Utility\PathUtility\stripPathSitePrefix
‪static string stripPathSitePrefix($path)
Definition: PathUtility.php:445
‪TYPO3\CMS\Core\Utility\PathUtility\isExtensionPath
‪static bool isExtensionPath(string $path)
Definition: PathUtility.php:121
‪TYPO3\CMS\Frontend\Resource\FilePathSanitizer
Definition: FilePathSanitizer.php:39
‪TYPO3\CMS\Core\Utility\PathUtility\getPublicResourceWebPath
‪static string getPublicResourceWebPath(string $resourcePath, bool $prefixWithSitePath=true)
Definition: PathUtility.php:98
‪TYPO3\CMS\Core\Resource\Exception\FileDoesNotExistException
Definition: FileDoesNotExistException.php:21
‪TYPO3\CMS\Core\Core\Environment\getFrameworkBasePath
‪static string getFrameworkBasePath()
Definition: Environment.php:287
‪TYPO3\CMS\Frontend\Resource\FilePathSanitizer\$allowedPaths
‪array $allowedPaths
Definition: FilePathSanitizer.php:46
‪TYPO3\CMS\Frontend\Resource\FilePathSanitizer\__construct
‪__construct()
Definition: FilePathSanitizer.php:51
‪TYPO3\CMS\Core\Resource\Exception\InvalidFileException
Definition: InvalidFileException.php:23
‪TYPO3\CMS\Frontend\Resource\FilePathSanitizer\makeRelative
‪makeRelative(string $absoluteFilePath, string $originalFilePath, bool $isExtensionPath)
Definition: FilePathSanitizer.php:118
‪TYPO3\CMS\Core\Core\Environment\getBackendPath
‪static string getBackendPath()
Definition: Environment.php:276
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\Core\Environment
Definition: Environment.php:43
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:50
‪TYPO3\CMS\Core\Resource\Exception\InvalidPathException
Definition: InvalidPathException.php:23
‪TYPO3\CMS\Core\Resource\Exception\InvalidFileNameException
Definition: InvalidFileNameException.php:23
‪TYPO3\CMS\Frontend\Resource\FilePathSanitizer\sanitize
‪string sanitize(string $originalFileName, ?bool $allowExtensionPath=null)
Definition: FilePathSanitizer.php:79
‪TYPO3\CMS\Core\Core\Environment\getExtensionsPath
‪static string getExtensionsPath()
Definition: Environment.php:297