Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
SecurityHeadersMiddleware
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
2 / 2
2
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 process
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5namespace App\Shared\Security;
6
7use Psr\Http\Message\ResponseInterface;
8use Psr\Http\Message\ServerRequestInterface;
9use Psr\Http\Server\MiddlewareInterface;
10use Psr\Http\Server\RequestHandlerInterface;
11
12 class SecurityHeadersMiddleware implements MiddlewareInterface
13{
14    public function __construct(
15        private  CspNonceService $nonceService
16    ) {}
17
18    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
19    {
20        $response = $handler->handle($request);
21
22        $nonce = $this->nonceService->getNonce();
23
24        // 1. Content-Security-Policy (CSP)
25        $csp = sprintf(
26            "default-src 'self'; script-src 'self' 'nonce-%s'; style-src 'self' 'unsafe-inline'; frame-ancestors 'none';",
27            $nonce
28        );
29        $response = $response->withHeader('Content-Security-Policy', $csp);
30
31        // 2. Strict-Transport-Security (HSTS)
32        $response = $response->withHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains; preload');
33
34        // 3. X-Content-Type-Options
35        $response = $response->withHeader('X-Content-Type-Options', 'nosniff');
36
37        // 4. X-Frame-Options
38        $response = $response->withHeader('X-Frame-Options', 'DENY');
39
40        // 5. Referrer-Policy
41        $response = $response->withHeader('Referrer-Policy', 'strict-origin-when-cross-origin');
42
43        // 6. Permissions-Policy
44        $response = $response->withHeader('Permissions-Policy', 'geolocation=(), camera=(), microphone=()');
45
46        return $response;
47    }
48}