X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/fd44e4ba74b7615e196dcafa4f1eddc634c0b44d..refs/pull/3260/head:/app/Http/Middleware/ApplyCspRules.php diff --git a/app/Http/Middleware/ApplyCspRules.php b/app/Http/Middleware/ApplyCspRules.php index 2889d80b0..6c9d14e7b 100644 --- a/app/Http/Middleware/ApplyCspRules.php +++ b/app/Http/Middleware/ApplyCspRules.php @@ -2,14 +2,22 @@ namespace BookStack\Http\Middleware; +use BookStack\Util\CspService; use Closure; use Illuminate\Http\Request; -use Illuminate\Support\Str; -use Symfony\Component\HttpFoundation\Response; - class ApplyCspRules { + /** + * @var CspService + */ + protected $cspService; + + public function __construct(CspService $cspService) + { + $this->cspService = $cspService; + } + /** * Handle an incoming request. * @@ -20,50 +28,18 @@ class ApplyCspRules */ public function handle($request, Closure $next) { - $nonce = Str::random(24); - view()->share('cspNonce', $nonce); - - // TODO - Assess whether image/style/iframe CSP rules should be set - // TODO - Extract nonce application to custom head content in a way that's cacheable. - // TODO - Fix remaining CSP issues and test lots + view()->share('cspNonce', $this->cspService->getNonce()); + if ($this->cspService->allowedIFrameHostsConfigured()) { + config()->set('session.same_site', 'none'); + } $response = $next($request); - $this->setFrameAncestors($response); - $this->setScriptSrc($response, $nonce); + $this->cspService->setFrameAncestors($response); + $this->cspService->setScriptSrc($response); + $this->cspService->setObjectSrc($response); + $this->cspService->setBaseUri($response); return $response; } - - /** - * Sets CSP 'script-src' headers to restrict the forms of script that can - * run on the page. - */ - public function setScriptSrc(Response $response, string $nonce) - { - $parts = [ - '\'self\'', - '\'nonce-' . $nonce . '\'', - '\'strict-dynamic\'', - ]; - $response->headers->set('Content-Security-Policy', 'script-src ' . implode(' ', $parts)); - } - - /** - * Sets CSP "frame-ancestors" headers to restrict the hosts that BookStack can be - * iframed within. Also adjusts the cookie samesite options so that cookies will - * operate in the third-party context. - */ - protected function setFrameAncestors(Response $response) - { - $iframeHosts = collect(explode(' ', config('app.iframe_hosts', '')))->filter(); - - if ($iframeHosts->count() > 0) { - config()->set('session.same_site', 'none'); - } - - $iframeHosts->prepend("'self'"); - $cspValue = 'frame-ancestors ' . $iframeHosts->join(' '); - $response->headers->set('Content-Security-Policy', $cspValue); - } }