‪TYPO3CMS  ‪main
ContentSecurityPolicyHeaders.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\Http\Message\ResponseInterface;
21 use Psr\Http\Message\ServerRequestInterface;
22 use Psr\Http\Server\MiddlewareInterface;
23 use Psr\Http\Server\RequestHandlerInterface;
24 use Psr\Log\LoggerInterface;
31 
37 final class ‪ContentSecurityPolicyHeaders implements MiddlewareInterface
38 {
39  public function ‪__construct(
40  private readonly ‪Features $features,
41  private readonly ‪RequestId $requestId,
42  private readonly LoggerInterface $logger,
43  private readonly ‪FrontendInterface $cache,
44  private readonly ‪PolicyProvider $policyProvider,
45  ) {}
46 
47  public function ‪process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
48  {
49  // return early in case CSP shall not be used
50  if (!$this->features->isFeatureEnabled('security.frontend.enforceContentSecurityPolicy')) {
51  return $handler->handle($request);
52  }
53  // make sure, the nonce value is set before processing the remaining middlewares
54  $request = $request->withAttribute('nonce', $this->requestId->nonce);
55  $response = $handler->handle($request);
56 
57  $site = $request->getAttribute('site');
58  $scope = ‪Scope::frontendSite($site);
59  if ($response->hasHeader('Content-Security-Policy') || $response->hasHeader('Content-Security-Policy-Report-Only')) {
60  $this->logger->info('Content-Security-Policy not enforced due to existence of custom header', [
61  'scope' => (string)$scope,
62  'uri' => (string)$request->getUri(),
63  ]);
64  return $response;
65  }
66 
67  $policy = $this->policyProvider->provideFor($scope);
68  if ($policy->isEmpty()) {
69  return $response;
70  }
71  $reportingUri = $this->policyProvider->getReportingUrlFor($scope, $request);
72  if ($reportingUri !== null) {
73  $policy = $policy->report(‪UriValue::fromUri($reportingUri));
74  }
75  return $response->withHeader('Content-Security-Policy', $policy->compile($this->requestId->nonce, $this->cache));
76  }
77 }
‪TYPO3\CMS\Frontend\Middleware\ContentSecurityPolicyHeaders
Definition: ContentSecurityPolicyHeaders.php:38
‪TYPO3\CMS\Frontend\Middleware\ContentSecurityPolicyHeaders\__construct
‪__construct(private readonly Features $features, private readonly RequestId $requestId, private readonly LoggerInterface $logger, private readonly FrontendInterface $cache, private readonly PolicyProvider $policyProvider,)
Definition: ContentSecurityPolicyHeaders.php:39
‪TYPO3\CMS\Frontend\Middleware
Definition: BackendUserAuthenticator.php:18
‪TYPO3\CMS\Core\Core\RequestId
Definition: RequestId.php:26
‪TYPO3\CMS\Core\Configuration\Features
Definition: Features.php:56
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\Scope
Definition: Scope.php:30
‪TYPO3\CMS\Core\Cache\Frontend\FrontendInterface
Definition: FrontendInterface.php:22
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\Scope\frontendSite
‪static frontendSite(?SiteInterface $site)
Definition: Scope.php:54
‪TYPO3\CMS\Frontend\Middleware\ContentSecurityPolicyHeaders\process
‪process(ServerRequestInterface $request, RequestHandlerInterface $handler)
Definition: ContentSecurityPolicyHeaders.php:47
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\UriValue
Definition: UriValue.php:29
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\PolicyProvider
Definition: PolicyProvider.php:38
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\UriValue\fromUri
‪static fromUri(UriInterface $other)
Definition: UriValue.php:34