diff --git a/src/Header.php b/src/Header.php index f026fb03f6..929b944144 100644 --- a/src/Header.php +++ b/src/Header.php @@ -376,13 +376,6 @@ class Header 'Permissions-Policy' => 'fullscreen=(self), interest-cohort=()', ]; - /* Prevent against ClickJacking by disabling framing */ - if ($this->config->config->AllowThirdPartyFraming === 'sameorigin') { - $headers['X-Frame-Options'] = 'SAMEORIGIN'; - } elseif ($this->config->config->AllowThirdPartyFraming !== true) { - $headers['X-Frame-Options'] = 'DENY'; - } - $headers = array_merge($headers, Core::getNoCacheHeaders($clock ?? new Clock())); /** @@ -445,6 +438,13 @@ class Header "style-src 'self' 'unsafe-inline'" . $captchaUrl . $cspAllow, ]; + // Prevent click-jacking by disabling inline-framing + if ($this->config->config->AllowThirdPartyFraming === 'sameorigin') { + $csp[] = "frame-ancestors 'self'"; + } elseif ($this->config->config->AllowThirdPartyFraming !== true) { + $csp[] = "frame-ancestors 'none'"; + } + return implode('; ', $csp) . ';'; } diff --git a/tests/unit/HeaderTest.php b/tests/unit/HeaderTest.php index d832f513d6..da19212ce9 100644 --- a/tests/unit/HeaderTest.php +++ b/tests/unit/HeaderTest.php @@ -186,7 +186,6 @@ class HeaderTest extends AbstractTestCase string $privateKey, string $publicKey, string $captchaCsp, - string|null $expectedFrameOptions, string $expectedCsp, ): void { $header = $this->getNewHeaderInstance(); @@ -206,21 +205,17 @@ class HeaderTest extends AbstractTestCase 'X-Permitted-Cross-Domain-Policies' => 'none', 'X-Robots-Tag' => 'noindex, nofollow', 'Permissions-Policy' => 'fullscreen=(self), interest-cohort=()', - 'X-Frame-Options' => $expectedFrameOptions ?? '', 'Expires' => 'Wed, 21 Oct 2015 07:28:00 GMT', 'Cache-Control' => 'no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0', 'Pragma' => 'no-cache', 'Last-Modified' => 'Wed, 21 Oct 2015 07:28:00 GMT', 'Content-Type' => 'text/html; charset=utf-8', ]; - if ($expectedFrameOptions === null) { - unset($expected['X-Frame-Options']); - } self::assertSame($expected, $header->getHttpHeaders(MockClock::from('2015-10-21T05:28:00-02:00'))); } - /** @psalm-return list */ + /** @psalm-return list */ public static function providerForTestGetHttpHeaders(): array { return [ @@ -230,12 +225,12 @@ class HeaderTest extends AbstractTestCase '', '', '', - 'DENY', "default-src 'self';" . " img-src 'self' data: tile.openstreetmap.org;" . " object-src 'none';" . " script-src 'self' 'unsafe-inline' 'unsafe-eval';" . " style-src 'self' 'unsafe-inline';" + . " frame-ancestors 'none';", ], [ 'sameorigin', @@ -243,12 +238,12 @@ class HeaderTest extends AbstractTestCase 'PrivateKey', 'PublicKey', 'captcha.tld csp.tld', - 'SAMEORIGIN', "default-src 'self' captcha.tld csp.tld example.com example.net;" . " img-src 'self' data: captcha.tld csp.tld example.com example.net tile.openstreetmap.org;" . " object-src 'none';" . " script-src 'self' 'unsafe-inline' 'unsafe-eval' captcha.tld csp.tld example.com example.net;" . " style-src 'self' 'unsafe-inline' captcha.tld csp.tld example.com example.net;" + . " frame-ancestors 'self';", ], [ true, @@ -256,7 +251,6 @@ class HeaderTest extends AbstractTestCase 'PrivateKey', 'PublicKey', 'captcha.tld csp.tld', - null, "default-src 'self' captcha.tld csp.tld;" . " img-src 'self' data: captcha.tld csp.tld tile.openstreetmap.org;" . " object-src 'none';"