‪TYPO3CMS  11.5
RouteDispatcher.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of the TYPO3 CMS project.
5  *
6  * It is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU General Public License, either version 2
8  * of the License, or any later version.
9  *
10  * For the full copyright and license information, please read the
11  * LICENSE.txt file that was distributed with this source code.
12  *
13  * The TYPO3 project - inspiring people to share!
14  */
15 
17 
18 use Psr\Container\ContainerInterface;
19 use Psr\Http\Message\ResponseInterface;
20 use Psr\Http\Message\ServerRequestInterface;
26 use TYPO3\CMS\Backend\Utility\BackendUtility;
36 
41 {
43 
44  public function ‪__construct(ContainerInterface ‪$container, ‪UriBuilder ‪$uriBuilder)
45  {
46  parent::__construct(‪$container);
47  $this->uriBuilder = ‪$uriBuilder;
48  }
49 
59  public function ‪dispatch(ServerRequestInterface $request): ResponseInterface
60  {
62  $route = $request->getAttribute('route');
63 
64  $enforceReferrerResponse = $this->‪enforceReferrer($request, $route);
65  if ($enforceReferrerResponse instanceof ResponseInterface) {
66  return $enforceReferrerResponse;
67  }
68  // Ensure that a token exists, and the token is requested, if the route requires a valid token
69  $this->‪assertRequestToken($request, $route);
70 
71  if ($route->hasOption('module')) {
72  $this->‪addAndValidateModuleConfiguration($request, $route);
73 
74  // This module request (which is usually opened inside the list_frame)
75  // has been issued from a toplevel browser window (e.g. a link was opened in a new tab).
76  // Redirect to open the module as frame inside the TYPO3 backend layout.
77  // HEADS UP: This header will only be available in secure connections (https:// or .localhost TLD)
78  if ($request->getHeaderLine('Sec-Fetch-Dest') === 'document') {
79  return new ‪RedirectResponse(
80  $this->uriBuilder->buildUriWithRedirect(
81  'main',
82  [],
83  ‪RouteRedirect::createFromRoute($route, $request->getQueryParams())
84  )
85  );
86  }
87  }
88  $targetIdentifier = $route->getOption('target');
89  $target = $this->‪getCallableFromTarget($targetIdentifier);
90  $arguments = [$request];
91  return $target(...$arguments);
92  }
93 
99  protected function ‪getFormProtection()
100  {
102  }
103 
113  protected function ‪enforceReferrer(ServerRequestInterface $request, ‪Route $route): ?ResponseInterface
114  {
115  $features = GeneralUtility::makeInstance(Features::class);
116  if (!$features->isFeatureEnabled('security.backend.enforceReferrer')) {
117  return null;
118  }
119  $referrerFlags = ‪GeneralUtility::trimExplode(',', $route->‪getOption('referrer') ?? '', true);
120  if (!in_array('required', $referrerFlags, true)) {
121  return null;
122  }
123  $referrerEnforcer = GeneralUtility::makeInstance(ReferrerEnforcer::class, $request);
124  return $referrerEnforcer->handle([
125  'flags' => $referrerFlags,
126  'subject' => $route->‪getPath(),
127  ]);
128  }
129 
139  protected function ‪assertRequestToken(ServerRequestInterface $request, ‪Route $route): void
140  {
141  if ($route->‪getOption('access') === 'public') {
142  return;
143  }
144  $token = (string)($request->getParsedBody()['token'] ?? $request->getQueryParams()['token'] ?? '');
145  if (empty($token)) {
147  sprintf('Invalid request for route "%s"', $route->‪getPath()),
148  1627905246
149  );
150  }
151  if (!$this->‪getFormProtection()->validateToken($token, 'route', $route->‪getOption('_identifier'))) {
153  sprintf('Invalid request for route "%s"', $route->‪getPath()),
154  1425389455
155  );
156  }
157  }
158 
167  protected function ‪addAndValidateModuleConfiguration(ServerRequestInterface $request, ‪Route $route)
168  {
169  $moduleName = $route->‪getOption('moduleName');
170  $moduleConfiguration = $this->‪getModuleConfiguration($moduleName);
171  $route->‪setOption('moduleConfiguration', $moduleConfiguration);
172 
173  $backendUserAuthentication = ‪$GLOBALS['BE_USER'];
174 
175  // Check permissions and exit if the user has no permission for entry
176  $backendUserAuthentication->modAccess($moduleConfiguration);
177  // '' for "no value found at all" to guarantee that the following if condition fails.
178  $id = $request->getQueryParams()['id'] ?? $request->getParsedBody()['id'] ?? '';
179  if (‪MathUtility::canBeInterpretedAsInteger($id) && $id > 0) {
180  $permClause = $backendUserAuthentication->getPagePermsClause(‪Permission::PAGE_SHOW);
181  // Check page access
182  if (!is_array(BackendUtility::readPageAccess($id, $permClause))) {
183  // Check if page has been deleted
184  $deleteField = ‪$GLOBALS['TCA']['pages']['ctrl']['delete'];
185  $pageInfo = BackendUtility::getRecord('pages', $id, $deleteField, $permClause ? ' AND ' . $permClause : '', false);
186  if (!($pageInfo[$deleteField] ?? false)) {
187  throw new \RuntimeException('You don\'t have access to this page', 1289917924);
188  }
189  }
190  }
191  }
192 
200  protected function ‪getModuleConfiguration($moduleName)
201  {
202  if (!isset(‪$GLOBALS['TBE_MODULES']['_configuration'][$moduleName])) {
203  throw new \RuntimeException('Module ' . $moduleName . ' is not configured.', 1289918325);
204  }
205  return ‪$GLOBALS['TBE_MODULES']['_configuration'][$moduleName];
206  }
207 }
‪TYPO3\CMS\Core\Http\Security\ReferrerEnforcer
Definition: ReferrerEnforcer.php:31
‪TYPO3\CMS\Core\Utility\GeneralUtility\trimExplode
‪static list< string > trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
Definition: GeneralUtility.php:999
‪TYPO3\CMS\Core\Http\Dispatcher
Definition: Dispatcher.php:30
‪TYPO3\CMS\Backend\Routing\Route\getPath
‪string getPath()
Definition: Route.php:51
‪TYPO3\CMS\Backend\Http\RouteDispatcher
Definition: RouteDispatcher.php:41
‪TYPO3\CMS\Core\FormProtection\FormProtectionFactory\get
‪static TYPO3 CMS Core FormProtection AbstractFormProtection get($classNameOrType='default',... $constructorArguments)
Definition: FormProtectionFactory.php:73
‪TYPO3\CMS\Backend\Http\RouteDispatcher\enforceReferrer
‪ResponseInterface null enforceReferrer(ServerRequestInterface $request, Route $route)
Definition: RouteDispatcher.php:113
‪TYPO3\CMS\Core\Utility\MathUtility\canBeInterpretedAsInteger
‪static bool canBeInterpretedAsInteger($var)
Definition: MathUtility.php:74
‪TYPO3\CMS\Backend\Routing\Route\getOption
‪mixed getOption($name)
Definition: Route.php:143
‪TYPO3\CMS\Backend\Routing\Exception\InvalidRequestTokenException
Definition: InvalidRequestTokenException.php:23
‪TYPO3\CMS\Backend\Http
Definition: Application.php:18
‪TYPO3\CMS\Backend\Http\RouteDispatcher\__construct
‪__construct(ContainerInterface $container, UriBuilder $uriBuilder)
Definition: RouteDispatcher.php:44
‪TYPO3\CMS\Core\Http\Dispatcher\$container
‪ContainerInterface $container
Definition: Dispatcher.php:33
‪TYPO3\CMS\Backend\Routing\Route
Definition: Route.php:24
‪TYPO3\CMS\Backend\Http\RouteDispatcher\assertRequestToken
‪assertRequestToken(ServerRequestInterface $request, Route $route)
Definition: RouteDispatcher.php:139
‪TYPO3\CMS\Core\Type\Bitmask\Permission
Definition: Permission.php:26
‪TYPO3\CMS\Core\Http\Dispatcher\getCallableFromTarget
‪callable getCallableFromTarget($target)
Definition: Dispatcher.php:63
‪TYPO3\CMS\Backend\Http\RouteDispatcher\addAndValidateModuleConfiguration
‪addAndValidateModuleConfiguration(ServerRequestInterface $request, Route $route)
Definition: RouteDispatcher.php:167
‪TYPO3\CMS\Backend\Routing\RouteRedirect
Definition: RouteRedirect.php:30
‪TYPO3\CMS\Backend\Routing\UriBuilder
Definition: UriBuilder.php:40
‪TYPO3\CMS\Backend\Routing\Exception\MissingRequestTokenException
Definition: MissingRequestTokenException.php:23
‪TYPO3\CMS\Backend\Http\RouteDispatcher\getFormProtection
‪AbstractFormProtection getFormProtection()
Definition: RouteDispatcher.php:99
‪TYPO3\CMS\Core\Configuration\Features
Definition: Features.php:56
‪TYPO3\CMS\Core\Type\Bitmask\Permission\PAGE_SHOW
‪const PAGE_SHOW
Definition: Permission.php:35
‪TYPO3\CMS\Core\Http\RedirectResponse
Definition: RedirectResponse.php:28
‪TYPO3\CMS\Core\FormProtection\AbstractFormProtection
Definition: AbstractFormProtection.php:30
‪TYPO3\CMS\Core\FormProtection\FormProtectionFactory
Definition: FormProtectionFactory.php:48
‪TYPO3\CMS\Backend\Http\RouteDispatcher\$uriBuilder
‪UriBuilder $uriBuilder
Definition: RouteDispatcher.php:42
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Backend\Http\RouteDispatcher\dispatch
‪ResponseInterface dispatch(ServerRequestInterface $request)
Definition: RouteDispatcher.php:59
‪TYPO3\CMS\Core\Utility\MathUtility
Definition: MathUtility.php:22
‪TYPO3\CMS\Backend\Routing\RouteRedirect\createFromRoute
‪static createFromRoute(Route $route, array $parameters)
Definition: RouteRedirect.php:53
‪TYPO3\CMS\Backend\Routing\Route\setOption
‪Route setOption($name, $value)
Definition: Route.php:131
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:50
‪TYPO3\CMS\Backend\Http\RouteDispatcher\getModuleConfiguration
‪array getModuleConfiguration($moduleName)
Definition: RouteDispatcher.php:200