19c88b4e9SGreg Roach<?php 29c88b4e9SGreg Roach 39c88b4e9SGreg Roach/** 49c88b4e9SGreg Roach * webtrees: online genealogy 5d11be702SGreg Roach * Copyright (C) 2023 webtrees development team 69c88b4e9SGreg Roach * This program is free software: you can redistribute it and/or modify 79c88b4e9SGreg Roach * it under the terms of the GNU General Public License as published by 89c88b4e9SGreg Roach * the Free Software Foundation, either version 3 of the License, or 99c88b4e9SGreg Roach * (at your option) any later version. 109c88b4e9SGreg Roach * This program is distributed in the hope that it will be useful, 119c88b4e9SGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of 129c88b4e9SGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 139c88b4e9SGreg Roach * GNU General Public License for more details. 149c88b4e9SGreg Roach * You should have received a copy of the GNU General Public License 1589f7189bSGreg Roach * along with this program. If not, see <https://www.gnu.org/licenses/>. 169c88b4e9SGreg Roach */ 179c88b4e9SGreg Roach 189c88b4e9SGreg Roachdeclare(strict_types=1); 199c88b4e9SGreg Roach 209c88b4e9SGreg Roachnamespace Fisharebest\Webtrees\Http\Middleware; 219c88b4e9SGreg Roach 22*f5f6ea63SGreg Roachuse Fisharebest\Webtrees\Validator; 239c88b4e9SGreg Roachuse Psr\Http\Message\ResponseInterface; 249c88b4e9SGreg Roachuse Psr\Http\Message\ServerRequestInterface; 259c88b4e9SGreg Roachuse Psr\Http\Server\MiddlewareInterface; 269c88b4e9SGreg Roachuse Psr\Http\Server\RequestHandlerInterface; 279c88b4e9SGreg Roach 289c88b4e9SGreg Roach/** 299c88b4e9SGreg Roach * Middleware to set security-related HTTP headers. 309c88b4e9SGreg Roach */ 319c88b4e9SGreg Roachclass SecurityHeaders implements MiddlewareInterface 329c88b4e9SGreg Roach{ 339c88b4e9SGreg Roach private const SECURITY_HEADERS = [ 34a9e82893SGreg Roach 'Permissions-Policy' => 'browsing-topics=()', 359c88b4e9SGreg Roach 'Referrer-Policy' => 'same-origin', 369c88b4e9SGreg Roach 'X-Content-Type-Options' => 'nosniff', 379c88b4e9SGreg Roach 'X-Frame-Options' => 'SAMEORIGIN', 389c88b4e9SGreg Roach 'X-XSS-Protection' => '1; mode=block', 399c88b4e9SGreg Roach ]; 409c88b4e9SGreg Roach 419c88b4e9SGreg Roach /** 429c88b4e9SGreg Roach * @param ServerRequestInterface $request 439c88b4e9SGreg Roach * @param RequestHandlerInterface $handler 449c88b4e9SGreg Roach * 459c88b4e9SGreg Roach * @return ResponseInterface 469c88b4e9SGreg Roach */ 479c88b4e9SGreg Roach public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface 489c88b4e9SGreg Roach { 499c88b4e9SGreg Roach $response = $handler->handle($request); 509c88b4e9SGreg Roach 519c88b4e9SGreg Roach foreach (self::SECURITY_HEADERS as $header_name => $header_value) { 529c88b4e9SGreg Roach // Don't overwrite existing headers. 539c88b4e9SGreg Roach if ($response->getHeader($header_name) === []) { 549c88b4e9SGreg Roach $response = $response->withHeader($header_name, $header_value); 559c88b4e9SGreg Roach } 569c88b4e9SGreg Roach } 579c88b4e9SGreg Roach 58*f5f6ea63SGreg Roach $base_url = Validator::attributes($request)->string('base_url'); 59*f5f6ea63SGreg Roach 60*f5f6ea63SGreg Roach if (str_starts_with($base_url, 'https://') && $response->getHeader('Strict-Transport-Security') === []) { 61*f5f6ea63SGreg Roach $response = $response->withHeader('Strict-Transport-Security', 'max-age=31536000'); 62*f5f6ea63SGreg Roach } 63*f5f6ea63SGreg Roach 649c88b4e9SGreg Roach return $response; 659c88b4e9SGreg Roach } 669c88b4e9SGreg Roach} 67