diff --git a/src/Symfony/Bundle/WebProfilerBundle/Csp/ContentSecurityPolicyHandler.php b/src/Symfony/Bundle/WebProfilerBundle/Csp/ContentSecurityPolicyHandler.php index e62895fe6d2b2..f75d29aea78d6 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Csp/ContentSecurityPolicyHandler.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Csp/ContentSecurityPolicyHandler.php @@ -133,12 +133,11 @@ private function updateCspHeaders(Response $response, array $nonces = []) continue; } if (!isset($headers[$header][$type])) { - if (isset($headers[$header]['default-src'])) { - $headers[$header][$type] = $headers[$header]['default-src']; - } else { - // If there is no script-src/style-src and no default-src, no additional rules required. + if (null === $fallback = $this->getDirectiveFallback($directives, $type)) { continue; } + + $headers[$header][$type] = $fallback; } $ruleIsSet = true; if (!\in_array('\'unsafe-inline\'', $headers[$header][$type], true)) { @@ -218,9 +217,7 @@ private function authorizesInline(array $directivesSet, $type) { if (isset($directivesSet[$type])) { $directives = $directivesSet[$type]; - } elseif (isset($directivesSet['default-src'])) { - $directives = $directivesSet['default-src']; - } else { + } elseif (null === $directives = $this->getDirectiveFallback($directivesSet, $type)) { return false; } @@ -244,6 +241,16 @@ private function hasHashOrNonce(array $directives) return false; } + private function getDirectiveFallback(array $directiveSet, $type) + { + if (\in_array($type, ['script-src-elem', 'style-src-elem'], true) || !isset($directiveSet['default-src'])) { + // Let the browser fallback on it's own + return null; + } + + return $directiveSet['default-src']; + } + /** * Retrieves the Content-Security-Policy headers (either X-Content-Security-Policy or Content-Security-Policy) from * a response. diff --git a/src/Symfony/Bundle/WebProfilerBundle/Tests/Csp/ContentSecurityPolicyHandlerTest.php b/src/Symfony/Bundle/WebProfilerBundle/Tests/Csp/ContentSecurityPolicyHandlerTest.php index 349db2aaf75b4..3afe8a95fcd9c 100644 --- a/src/Symfony/Bundle/WebProfilerBundle/Tests/Csp/ContentSecurityPolicyHandlerTest.php +++ b/src/Symfony/Bundle/WebProfilerBundle/Tests/Csp/ContentSecurityPolicyHandlerTest.php @@ -131,7 +131,14 @@ public function provideRequestAndResponsesForOnKernelResponse() ['csp_script_nonce' => $nonce, 'csp_style_nonce' => $nonce], $this->createRequest(), $this->createResponse(['Content-Security-Policy' => 'default-src \'self\' domain.com; script-src \'self\' \'unsafe-inline\'', 'Content-Security-Policy-Report-Only' => 'default-src \'self\' domain-report-only.com; script-src \'self\' \'unsafe-inline\'']), - ['Content-Security-Policy' => 'default-src \'self\' domain.com; script-src \'self\' \'unsafe-inline\'; script-src-elem \'self\' domain.com \'unsafe-inline\' \'nonce-'.$nonce.'\'; style-src \'self\' domain.com \'unsafe-inline\' \'nonce-'.$nonce.'\'; style-src-elem \'self\' domain.com \'unsafe-inline\' \'nonce-'.$nonce.'\'', 'Content-Security-Policy-Report-Only' => 'default-src \'self\' domain-report-only.com; script-src \'self\' \'unsafe-inline\'; script-src-elem \'self\' domain-report-only.com \'unsafe-inline\' \'nonce-'.$nonce.'\'; style-src \'self\' domain-report-only.com \'unsafe-inline\' \'nonce-'.$nonce.'\'; style-src-elem \'self\' domain-report-only.com \'unsafe-inline\' \'nonce-'.$nonce.'\'', 'X-Content-Security-Policy' => null], + ['Content-Security-Policy' => 'default-src \'self\' domain.com; script-src \'self\' \'unsafe-inline\'; style-src \'self\' domain.com \'unsafe-inline\' \'nonce-'.$nonce.'\'', 'Content-Security-Policy-Report-Only' => 'default-src \'self\' domain-report-only.com; script-src \'self\' \'unsafe-inline\'; style-src \'self\' domain-report-only.com \'unsafe-inline\' \'nonce-'.$nonce.'\'', 'X-Content-Security-Policy' => null], + ], + [ + $nonce, + ['csp_script_nonce' => $nonce, 'csp_style_nonce' => $nonce], + $this->createRequest(), + $this->createResponse(['Content-Security-Policy' => 'default-src \'self\' domain.com; script-src \'self\' \'unsafe-inline\'; script-src-elem \'self\'; style-src \'self\' \'unsafe-inline\'; style-src-elem \'self\'', 'Content-Security-Policy-Report-Only' => 'default-src \'self\' domain-report-only.com; script-src \'self\' \'unsafe-inline\'; script-src-elem \'self\'; style-src \'self\' \'unsafe-inline\'; style-src-elem \'self\'']), + ['Content-Security-Policy' => 'default-src \'self\' domain.com; script-src \'self\' \'unsafe-inline\'; script-src-elem \'self\' \'unsafe-inline\' \'nonce-'.$nonce.'\'; style-src \'self\' \'unsafe-inline\'; style-src-elem \'self\' \'unsafe-inline\' \'nonce-'.$nonce.'\'', 'Content-Security-Policy-Report-Only' => 'default-src \'self\' domain-report-only.com; script-src \'self\' \'unsafe-inline\'; script-src-elem \'self\' \'unsafe-inline\' \'nonce-'.$nonce.'\'; style-src \'self\' \'unsafe-inline\'; style-src-elem \'self\' \'unsafe-inline\' \'nonce-'.$nonce.'\'', 'X-Content-Security-Policy' => null], ], [ $nonce,
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: