From ce7d8d36b60c79a336bb1c76da139017d73c0579 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Tim=20D=C3=BCsterhus?= Date: Thu, 19 May 2022 16:35:45 +0200 Subject: [PATCH] Add `AddAcpSecurityHeaders` middleware --- .../AddAcpSecurityHeaders.class.php | 54 +++++++++++++++++++ .../system/request/RequestHandler.class.php | 8 +-- 2 files changed, 56 insertions(+), 6 deletions(-) create mode 100644 wcfsetup/install/files/lib/http/middleware/AddAcpSecurityHeaders.class.php diff --git a/wcfsetup/install/files/lib/http/middleware/AddAcpSecurityHeaders.class.php b/wcfsetup/install/files/lib/http/middleware/AddAcpSecurityHeaders.class.php new file mode 100644 index 0000000000..429ca522b1 --- /dev/null +++ b/wcfsetup/install/files/lib/http/middleware/AddAcpSecurityHeaders.class.php @@ -0,0 +1,54 @@ + + * @package WoltLabSuite\Core\Http\Middleware + * @since 5.6 + */ +final class AddAcpSecurityHeaders implements MiddlewareInterface +{ + /** + * @inheritDoc + */ + public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface + { + if (!RequestHandler::getInstance()->isACPRequest()) { + return $handler->handle($request); + } + + // Also set the headers using the regular `\header()` call, because we might receive a + // LegacyPlaceholderResponse and we also need to protect requests to legacy controllers. + // If a proper PSR-7 response is returned the headers will be removed again and set on + // the response object. + \header('referrer-policy: same-origin'); + \header('cross-origin-opener-policy: same-origin'); + \header('cross-origin-resource-policy: same-site'); + + $response = $handler->handle($request); + + if ($response instanceof LegacyPlaceholderResponse) { + return $response; + } + + \header_remove('referrer-policy'); + \header_remove('cross-origin-opener-policy'); + \header_remove('cross-origin-resource-policy'); + + return $response->withHeader('referrer-policy', 'same-origin') + ->withHeader('cross-origin-opener-policy', 'same-origin') + ->withHeader('cross-origin-resource-policy', 'same-site'); + } +} diff --git a/wcfsetup/install/files/lib/system/request/RequestHandler.class.php b/wcfsetup/install/files/lib/system/request/RequestHandler.class.php index 43a93b59db..819dd3c6bf 100644 --- a/wcfsetup/install/files/lib/system/request/RequestHandler.class.php +++ b/wcfsetup/install/files/lib/system/request/RequestHandler.class.php @@ -5,6 +5,7 @@ namespace wcf\system\request; use Laminas\Diactoros\ServerRequestFactory; use Laminas\HttpHandlerRunner\Emitter\SapiEmitter; use wcf\http\LegacyPlaceholderResponse; +use wcf\http\middleware\AddAcpSecurityHeaders; use wcf\http\middleware\EnforceCacheControlPrivate; use wcf\http\middleware\EnforceFrameOptions; use wcf\http\Pipeline; @@ -98,13 +99,8 @@ class RequestHandler extends SingletonFactory $this->checkOfflineMode(); - if ($this->isACPRequest()) { - \header('referrer-policy: same-origin'); - \header('cross-origin-opener-policy: same-origin'); - \header('cross-origin-resource-policy: same-site'); - } - $pipeline = new Pipeline([ + new AddAcpSecurityHeaders(), new EnforceCacheControlPrivate(), new EnforceFrameOptions(), ]); -- 2.20.1