Skip to content
Permalink
Browse files Browse the repository at this point in the history
[SECURITY] Mitigate cross-site-scripting in FileDumpController
FileDumpController is used to expose stored files from the backend
user interface through a corresponding service-side process. Since
content-security-policy settings for files served directly by the
web server won't be applied, FileDumpController has to take care.

Resolves: #98221
Releases: main, 11.5, 10.4
Change-Id: I4fde10e48e33fa08452eddf876172f56b4f38e28
Security-Bulletin: TYPO3-CORE-SA-2022-009
Security-References: CVE-2022-36107
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/75718
Tested-by: Oliver Hader <oliver.hader@typo3.org>
Reviewed-by: Oliver Hader <oliver.hader@typo3.org>
  • Loading branch information
ohader committed Sep 13, 2022
1 parent 56af2bd commit bd58d2f
Showing 1 changed file with 22 additions and 4 deletions.
26 changes: 22 additions & 4 deletions typo3/sysext/core/Classes/Controller/FileDumpController.php
Expand Up @@ -29,8 +29,10 @@
use TYPO3\CMS\Core\Resource\ProcessedFile;
use TYPO3\CMS\Core\Resource\ProcessedFileRepository;
use TYPO3\CMS\Core\Resource\ResourceFactory;
use TYPO3\CMS\Core\Resource\ResourceInterface;
use TYPO3\CMS\Core\Resource\Security\FileNameValidator;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\PathUtility;

/**
* Class FileDumpController
Expand Down Expand Up @@ -77,7 +79,7 @@ public function dumpAction(ServerRequestInterface $request): ResponseInterface
$event = new ModifyFileDumpEvent($file, $request);
$event = $this->eventDispatcher->dispatch($event);
if ($event->isPropagationStopped()) {
return $event->getResponse();
return $this->applyContentSecurityPolicy($event->getFile(), $event->getResponse());
}
$file = $event->getFile();

Expand Down Expand Up @@ -120,10 +122,13 @@ public function dumpAction(ServerRequestInterface $request): ResponseInterface
$file = $file->process(ProcessedFile::CONTEXT_IMAGECROPSCALEMASK, $processingInstructions);
}

return $file->getStorage()->streamFile(
return $this->applyContentSecurityPolicy(
$file,
(bool)($parameters['dl'] ?? false),
$parameters['fn'] ?? null
$file->getStorage()->streamFile(
$file,
(bool)($parameters['dl'] ?? false),
$parameters['fn'] ?? null
)
);
}

Expand Down Expand Up @@ -230,4 +235,17 @@ protected function isFileValid(FileInterface $file): bool
|| GeneralUtility::makeInstance(FileNameValidator::class)
->isValid(basename($file->getIdentifier()));
}

/**
* Applies hard-coded content-security-policy (CSP) for file to be dumped.
*/
protected function applyContentSecurityPolicy(ResourceInterface $file, ResponseInterface $response): ResponseInterface
{
$extension = PathUtility::pathinfo($file->getName(), PATHINFO_EXTENSION);
// same as in `typo3/sysext/install/Resources/Private/FolderStructureTemplateFiles/resources-root-htaccess`
$policy = $extension === 'pdf' || $response->getHeaderLine('content-type') === 'application/pdf'
? "default-src 'self' 'unsafe-inline'; script-src 'none'; object-src 'self'; plugin-types application/pdf;"
: "default-src 'self'; script-src 'none'; style-src 'none'; object-src 'none';";
return $response->withAddedHeader('content-security-policy', $policy);
}
}

0 comments on commit bd58d2f

Please sign in to comment.