CSPMiddleware.php 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
  5. * SPDX-License-Identifier: AGPL-3.0-or-later
  6. */
  7. namespace OC\AppFramework\Middleware\Security;
  8. use OC\Security\CSP\ContentSecurityPolicyManager;
  9. use OC\Security\CSP\ContentSecurityPolicyNonceManager;
  10. use OCP\AppFramework\Controller;
  11. use OCP\AppFramework\Http\ContentSecurityPolicy;
  12. use OCP\AppFramework\Http\EmptyContentSecurityPolicy;
  13. use OCP\AppFramework\Http\Response;
  14. use OCP\AppFramework\Middleware;
  15. class CSPMiddleware extends Middleware {
  16. public function __construct(
  17. private ContentSecurityPolicyManager $policyManager,
  18. private ContentSecurityPolicyNonceManager $cspNonceManager,
  19. ) {
  20. }
  21. /**
  22. * Performs the default CSP modifications that may be injected by other
  23. * applications
  24. *
  25. * @param Controller $controller
  26. * @param string $methodName
  27. * @param Response $response
  28. * @return Response
  29. */
  30. public function afterController($controller, $methodName, Response $response): Response {
  31. $policy = !is_null($response->getContentSecurityPolicy()) ? $response->getContentSecurityPolicy() : new ContentSecurityPolicy();
  32. if (get_class($policy) === EmptyContentSecurityPolicy::class) {
  33. return $response;
  34. }
  35. $defaultPolicy = $this->policyManager->getDefaultPolicy();
  36. $defaultPolicy = $this->policyManager->mergePolicies($defaultPolicy, $policy);
  37. if ($this->cspNonceManager->browserSupportsCspV3()) {
  38. $defaultPolicy->useJsNonce($this->cspNonceManager->getNonce());
  39. }
  40. $response->setContentSecurityPolicy($defaultPolicy);
  41. return $response;
  42. }
  43. }