CSPMiddlewareTest.php 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  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 Test\AppFramework\Middleware\Security;
  8. use OC\AppFramework\Middleware\Security\CSPMiddleware;
  9. use OC\Security\CSP\ContentSecurityPolicy;
  10. use OC\Security\CSP\ContentSecurityPolicyManager;
  11. use OC\Security\CSP\ContentSecurityPolicyNonceManager;
  12. use OC\Security\CSRF\CsrfToken;
  13. use OC\Security\CSRF\CsrfTokenManager;
  14. use OCP\AppFramework\Controller;
  15. use OCP\AppFramework\Http\EmptyContentSecurityPolicy;
  16. use OCP\AppFramework\Http\Response;
  17. use PHPUnit\Framework\MockObject\MockObject;
  18. class CSPMiddlewareTest extends \Test\TestCase {
  19. /** @var CSPMiddleware|MockObject */
  20. private $middleware;
  21. /** @var Controller|MockObject */
  22. private $controller;
  23. /** @var ContentSecurityPolicyManager|MockObject */
  24. private $contentSecurityPolicyManager;
  25. /** @var CsrfTokenManager|MockObject */
  26. private $csrfTokenManager;
  27. /** @var ContentSecurityPolicyNonceManager|MockObject */
  28. private $cspNonceManager;
  29. protected function setUp(): void {
  30. parent::setUp();
  31. $this->controller = $this->createMock(Controller::class);
  32. $this->contentSecurityPolicyManager = $this->createMock(ContentSecurityPolicyManager::class);
  33. $this->csrfTokenManager = $this->createMock(CsrfTokenManager::class);
  34. $this->cspNonceManager = $this->createMock(ContentSecurityPolicyNonceManager::class);
  35. $this->middleware = new CSPMiddleware(
  36. $this->contentSecurityPolicyManager,
  37. $this->cspNonceManager,
  38. $this->csrfTokenManager
  39. );
  40. }
  41. public function testAfterController() {
  42. $this->cspNonceManager
  43. ->expects($this->once())
  44. ->method('browserSupportsCspV3')
  45. ->willReturn(false);
  46. $response = $this->createMock(Response::class);
  47. $defaultPolicy = new ContentSecurityPolicy();
  48. $defaultPolicy->addAllowedImageDomain('defaultpolicy');
  49. $currentPolicy = new ContentSecurityPolicy();
  50. $currentPolicy->addAllowedConnectDomain('currentPolicy');
  51. $mergedPolicy = new ContentSecurityPolicy();
  52. $mergedPolicy->addAllowedMediaDomain('mergedPolicy');
  53. $response
  54. ->expects($this->exactly(2))
  55. ->method('getContentSecurityPolicy')
  56. ->willReturn($currentPolicy);
  57. $this->contentSecurityPolicyManager
  58. ->expects($this->once())
  59. ->method('getDefaultPolicy')
  60. ->willReturn($defaultPolicy);
  61. $this->contentSecurityPolicyManager
  62. ->expects($this->once())
  63. ->method('mergePolicies')
  64. ->with($defaultPolicy, $currentPolicy)
  65. ->willReturn($mergedPolicy);
  66. $response->expects($this->once())
  67. ->method('setContentSecurityPolicy')
  68. ->with($mergedPolicy);
  69. $this->middleware->afterController($this->controller, 'test', $response);
  70. }
  71. public function testAfterControllerEmptyCSP() {
  72. $response = $this->createMock(Response::class);
  73. $emptyPolicy = new EmptyContentSecurityPolicy();
  74. $response->expects($this->any())
  75. ->method('getContentSecurityPolicy')
  76. ->willReturn($emptyPolicy);
  77. $response->expects($this->never())
  78. ->method('setContentSecurityPolicy');
  79. $this->middleware->afterController($this->controller, 'test', $response);
  80. }
  81. public function testAfterControllerWithContentSecurityPolicy3Support() {
  82. $this->cspNonceManager
  83. ->expects($this->once())
  84. ->method('browserSupportsCspV3')
  85. ->willReturn(true);
  86. $token = $this->createMock(CsrfToken::class);
  87. $token
  88. ->expects($this->once())
  89. ->method('getEncryptedValue')
  90. ->willReturn('MyEncryptedToken');
  91. $this->csrfTokenManager
  92. ->expects($this->once())
  93. ->method('getToken')
  94. ->willReturn($token);
  95. $response = $this->createMock(Response::class);
  96. $defaultPolicy = new ContentSecurityPolicy();
  97. $defaultPolicy->addAllowedImageDomain('defaultpolicy');
  98. $currentPolicy = new ContentSecurityPolicy();
  99. $currentPolicy->addAllowedConnectDomain('currentPolicy');
  100. $mergedPolicy = new ContentSecurityPolicy();
  101. $mergedPolicy->addAllowedMediaDomain('mergedPolicy');
  102. $response
  103. ->expects($this->exactly(2))
  104. ->method('getContentSecurityPolicy')
  105. ->willReturn($currentPolicy);
  106. $this->contentSecurityPolicyManager
  107. ->expects($this->once())
  108. ->method('getDefaultPolicy')
  109. ->willReturn($defaultPolicy);
  110. $this->contentSecurityPolicyManager
  111. ->expects($this->once())
  112. ->method('mergePolicies')
  113. ->with($defaultPolicy, $currentPolicy)
  114. ->willReturn($mergedPolicy);
  115. $response->expects($this->once())
  116. ->method('setContentSecurityPolicy')
  117. ->with($mergedPolicy);
  118. $this->assertEquals($response, $this->middleware->afterController($this->controller, 'test', $response));
  119. }
  120. }