‪TYPO3CMS  ‪main
RouteDispatcher.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 
20 use Psr\Container\ContainerInterface;
21 use Psr\Http\Message\ResponseInterface;
22 use Psr\Http\Message\ServerRequestInterface;
36 
41 {
42  public function ‪__construct(
43  protected readonly ‪FormProtectionFactory $formProtectionFactory,
44  protected readonly ‪AccessFactory $factory,
45  protected readonly ‪AccessStorage $storage,
46  ContainerInterface ‪$container,
47  ) {
48  parent::__construct(‪$container);
49  }
50 
60  public function ‪dispatch(ServerRequestInterface $request): ResponseInterface
61  {
63  $route = $request->getAttribute('route');
64 
65  $enforceReferrerResponse = $this->‪enforceReferrer($request, $route);
66  if ($enforceReferrerResponse !== null) {
67  return $enforceReferrerResponse;
68  }
69  // Ensure that a token exists, and the token is requested, if the route requires a valid token
70  $this->‪assertRequestToken($request, $route);
71  // Ensure that sudo-mode is active, if the route requires it
72  $this->‪assertSudoMode($request);
73 
74  $targetIdentifier = $route->getOption('target');
75  $target = $this->‪getCallableFromTarget($targetIdentifier);
76  $arguments = [$request];
77  return $target(...$arguments);
78  }
79 
85  protected function ‪enforceReferrer(ServerRequestInterface $request, ‪Route $route): ?ResponseInterface
86  {
87  $features = GeneralUtility::makeInstance(Features::class);
88  if (!$features->isFeatureEnabled('security.backend.enforceReferrer')) {
89  return null;
90  }
91  $referrerFlags = ‪GeneralUtility::trimExplode(',', $route->‪getOption('referrer') ?? '', true);
92  if (!in_array('required', $referrerFlags, true)) {
93  return null;
94  }
95  $referrerEnforcer = GeneralUtility::makeInstance(ReferrerEnforcer::class, $request);
96  return $referrerEnforcer->handle([
97  'flags' => $referrerFlags,
98  'subject' => $route->‪getPath(),
99  ]);
100  }
101 
109  protected function ‪assertRequestToken(ServerRequestInterface $request, ‪Route $route): void
110  {
111  if ($route->‪getOption('access') === 'public') {
112  return;
113  }
114  $token = (string)($request->getParsedBody()['token'] ?? $request->getQueryParams()['token'] ?? '');
115  if (empty($token)) {
117  sprintf('Invalid request for route "%s"', $route->‪getPath()),
118  1627905246
119  );
120  }
121  $formProtection = $this->formProtectionFactory->createFromRequest($request);
122  if (!$formProtection->validateToken($token, 'route', $route->‪getOption('_identifier'))) {
124  sprintf('Invalid request for route "%s"', $route->‪getPath()),
125  1425389455
126  );
127  }
128  }
129 
136  protected function ‪assertSudoMode(ServerRequestInterface $request): void
137  {
138  // #93160: [TASK] Do not require sudo mode in development context
139  if (‪Environment::getContext()->isDevelopment()) {
140  return;
141  }
143  $route = $request->getAttribute('route');
144  $settings = $route?->getOption('sudoMode') ?? null;
145  if (!is_array($settings)) {
146  return;
147  }
148 
149  // sudo mode settings for subject are fetched from the request again
150  $subject = $this->factory->buildRouteAccessSubject($request);
151  if ($this->storage->findGrantsBySubject($subject)) {
152  return;
153  }
154  // reuse existing matching claim, or create a new one
155  $claim = $this->storage->findClaimBySubject($subject)
156  ?? $this->factory->buildClaimForSubjectRequest($request, $subject);
158  'Sudo Mode Confirmation Required',
159  1605812020
160  ))->withClaim($claim);
161  }
162 }
‪TYPO3\CMS\Core\Http\Security\ReferrerEnforcer
Definition: ReferrerEnforcer.php:32
‪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\Backend\Routing\Route\getOption
‪mixed getOption($name)
Definition: Route.php:142
‪TYPO3\CMS\Backend\Routing\Exception\InvalidRequestTokenException
Definition: InvalidRequestTokenException.php:23
‪TYPO3\CMS\Backend\Security\SudoMode\Access\AccessStorage
Definition: AccessStorage.php:30
‪TYPO3\CMS\Backend\Http
Definition: Application.php:18
‪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:109
‪TYPO3\CMS\Core\Http\Dispatcher\getCallableFromTarget
‪callable getCallableFromTarget($target)
Definition: Dispatcher.php:63
‪TYPO3\CMS\Backend\Http\RouteDispatcher\assertSudoMode
‪assertSudoMode(ServerRequestInterface $request)
Definition: RouteDispatcher.php:136
‪TYPO3\CMS\Backend\Security\SudoMode\Access\AccessFactory
Definition: AccessFactory.php:30
‪TYPO3\CMS\Backend\Routing\UriBuilder
Definition: UriBuilder.php:44
‪TYPO3\CMS\Backend\Routing\Exception\MissingRequestTokenException
Definition: MissingRequestTokenException.php:23
‪TYPO3\CMS\Core\Configuration\Features
Definition: Features.php:56
‪TYPO3\CMS\Core\FormProtection\FormProtectionFactory
Definition: FormProtectionFactory.php:43
‪TYPO3\CMS\Backend\Http\RouteDispatcher\dispatch
‪ResponseInterface dispatch(ServerRequestInterface $request)
Definition: RouteDispatcher.php:60
‪TYPO3\CMS\Core\Core\Environment
Definition: Environment.php:41
‪TYPO3\CMS\Backend\Http\RouteDispatcher\__construct
‪__construct(protected readonly FormProtectionFactory $formProtectionFactory, protected readonly AccessFactory $factory, protected readonly AccessStorage $storage, ContainerInterface $container,)
Definition: RouteDispatcher.php:42
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Backend\Security\SudoMode\Exception\VerificationRequiredException
Definition: VerificationRequiredException.php:29
‪TYPO3\CMS\Backend\Http\RouteDispatcher\enforceReferrer
‪enforceReferrer(ServerRequestInterface $request, Route $route)
Definition: RouteDispatcher.php:85
‪TYPO3\CMS\Core\Core\Environment\getContext
‪static getContext()
Definition: Environment.php:128
‪TYPO3\CMS\Core\Utility\GeneralUtility\trimExplode
‪static list< string > trimExplode(string $delim, string $string, bool $removeEmptyValues=false, int $limit=0)
Definition: GeneralUtility.php:822