Skip to content

Commit

Permalink
[SECURITY] Avoid DoS when generating Error pages
Browse files Browse the repository at this point in the history
TYPO3 now uses a lock strategy to avoid having to many request
waiting for the generation of the error page (which cannot be
generated via the external HTTP request, as there might be not
enough workers / PHP processes available during a DoS attack).
If a lock is in place, it directly returns a generic error
response instead of waiting for the lock or that the error
page is retrieved/rendered.

Additionally, if the external error page could not be retrieved
(HTTP status code other than 200), it will also create a generic
response and cache that instead. This avoids keeping requesting
for the errounous external HTTP page.

This could happen when using external HTTP requests (Guzzle) to
resolve an error page (via PageContentErrorHandler) for 404 sites.

Resolves: #98384
Releases: 11.5, 10.4
Change-Id: Iae1cae882707a519b2cef85112525ea213a72eef
Security-Bulletin: TYPO3-CORE-SA-2022-012
Security-References: CVE-2022-23500
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/77083
Tested-by: Oliver Hader <oliver.hader@typo3.org>
Reviewed-by: Oliver Hader <oliver.hader@typo3.org>
  • Loading branch information
bmack authored and ohader committed Dec 13, 2022
1 parent 5e3e54d commit 73b46b6
Showing 1 changed file with 30 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,14 @@
use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Core\Cache\CacheManager;
use TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException;
use TYPO3\CMS\Core\Controller\ErrorPageController;
use TYPO3\CMS\Core\Exception\SiteNotFoundException;
use TYPO3\CMS\Core\Http\HtmlResponse;
use TYPO3\CMS\Core\Http\RequestFactory;
use TYPO3\CMS\Core\LinkHandling\LinkService;
use TYPO3\CMS\Core\Locking\Exception\LockAcquireWouldBlockException;
use TYPO3\CMS\Core\Locking\LockFactory;
use TYPO3\CMS\Core\Locking\LockingStrategyInterface;
use TYPO3\CMS\Core\Routing\InvalidRouteArgumentsException;
use TYPO3\CMS\Core\Site\Entity\Site;
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
Expand Down Expand Up @@ -86,9 +90,25 @@ public function handlePageError(ServerRequestInterface $request, string $message
$cacheContent = $cache->get($cacheIdentifier);

if (!$cacheContent && $resolvedUrl !== (string)$request->getUri()) {
$lockFactory = GeneralUtility::makeInstance(LockFactory::class);
$lock = $lockFactory->createLocker(
$cacheIdentifier,
LockingStrategyInterface::LOCK_CAPABILITY_EXCLUSIVE | LockingStrategyInterface::LOCK_CAPABILITY_NOBLOCK
);
try {
$locked = $lock->acquire(
LockingStrategyInterface::LOCK_CAPABILITY_EXCLUSIVE | LockingStrategyInterface::LOCK_CAPABILITY_NOBLOCK
);
if (!$locked) {
return $this->createGenericErrorResponse();
}

$subResponse = GeneralUtility::makeInstance(RequestFactory::class)
->request($resolvedUrl, 'GET', $this->getSubRequestOptions());
$lock->release();
} catch (LockAcquireWouldBlockException $_) {
$lock->release();
return $this->createGenericErrorResponse();
} catch (\Exception $e) {
throw new \RuntimeException('Error handler could not fetch error page "' . $resolvedUrl . '", reason: ' . $e->getMessage(), 1544172838);
}
Expand Down Expand Up @@ -124,6 +144,15 @@ public function handlePageError(ServerRequestInterface $request, string $message
return new HtmlResponse($content, $this->statusCode);
}

protected function createGenericErrorResponse(string $message = ''): ResponseInterface
{
$content = GeneralUtility::makeInstance(ErrorPageController::class)->errorAction(
'Page Not Found',
$message ?: 'The page did not exist or was inaccessible. Error page is being generated'
);
return new HtmlResponse($content, 503);
}

/**
* Returns request options for the subrequest and ensures, that a reasoneable timeout is present
*
Expand All @@ -134,7 +163,7 @@ protected function getSubRequestOptions(): array
$options = [];
if ((int)$GLOBALS['TYPO3_CONF_VARS']['HTTP']['timeout'] === 0) {
$options = [
'timeout' => 30
'timeout' => 10
];
}
return $options;
Expand Down

0 comments on commit 73b46b6

Please sign in to comment.