X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/b9a58859a4ef14b7971ca7d07318e1ac6f276b40..refs/pull/5280/head:/tests/SecurityHeaderTest.php diff --git a/tests/SecurityHeaderTest.php b/tests/SecurityHeaderTest.php index 78691badb..5d354e553 100644 --- a/tests/SecurityHeaderTest.php +++ b/tests/SecurityHeaderTest.php @@ -3,6 +3,7 @@ namespace Tests; use BookStack\Util\CspService; +use Illuminate\Testing\TestResponse; class SecurityHeaderTest extends TestCase { @@ -119,12 +120,48 @@ class SecurityHeaderTest extends TestCase $this->assertEquals('base-uri \'self\'', $scriptHeader); } - public function test_cache_control_headers_are_strict_on_responses_when_logged_in() + public function test_frame_src_csp_header_set() { + $resp = $this->get('/'); + $scriptHeader = $this->getCspHeader($resp, 'frame-src'); + $this->assertEquals('frame-src \'self\' https://*.draw.io https://*.youtube.com https://*.youtube-nocookie.com https://*.vimeo.com', $scriptHeader); + } + + public function test_frame_src_csp_header_has_drawio_host_added() + { + config()->set([ + 'app.iframe_sources' => 'https://example.com', + 'services.drawio' => 'https://diagrams.example.com/testing?cat=dog', + ]); + + $resp = $this->get('/'); + $scriptHeader = $this->getCspHeader($resp, 'frame-src'); + $this->assertEquals('frame-src \'self\' https://example.com https://diagrams.example.com', $scriptHeader); + } + + public function test_frame_src_csp_header_drawio_host_includes_port_if_existing() + { + config()->set([ + 'app.iframe_sources' => 'https://example.com', + 'services.drawio' => 'https://diagrams.example.com:8080/testing?cat=dog', + ]); + + $resp = $this->get('/'); + $scriptHeader = $this->getCspHeader($resp, 'frame-src'); + $this->assertEquals('frame-src \'self\' https://example.com https://diagrams.example.com:8080', $scriptHeader); + } + + public function test_cache_control_headers_are_set_on_responses() + { + // Public access + $resp = $this->get('/'); + $resp->assertHeader('Cache-Control', 'no-cache, no-store, private'); + $resp->assertHeader('Expires', 'Sun, 12 Jul 2015 19:01:00 GMT'); + + // Authed access $this->asEditor(); $resp = $this->get('/'); - $resp->assertHeader('Cache-Control', 'max-age=0, no-store, private'); - $resp->assertHeader('Pragma', 'no-cache'); + $resp->assertHeader('Cache-Control', 'no-cache, no-store, private'); $resp->assertHeader('Expires', 'Sun, 12 Jul 2015 19:01:00 GMT'); } @@ -133,10 +170,14 @@ class SecurityHeaderTest extends TestCase */ protected function getCspHeader(TestResponse $resp, string $type): string { - $cspHeaders = collect($resp->headers->all('Content-Security-Policy')); + $cspHeaders = explode('; ', $resp->headers->get('Content-Security-Policy')); + + foreach ($cspHeaders as $cspHeader) { + if (strpos($cspHeader, $type) === 0) { + return $cspHeader; + } + } - return $cspHeaders->filter(function ($val) use ($type) { - return strpos($val, $type) === 0; - })->first() ?? ''; + return ''; } }