Passed
Push — master ( 7af1bf...430d6b )
by
unknown
13:07
created

ContentSecurityPolicyHeader::isEmpty()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the TYPO3 CMS project.
7
 *
8
 * It is free software; you can redistribute it and/or modify it under
9
 * the terms of the GNU General Public License, either version 2
10
 * of the License, or any later version.
11
 *
12
 * For the full copyright and license information, please read the
13
 * LICENSE.txt file that was distributed with this source code.
14
 *
15
 * The TYPO3 project - inspiring people to share!
16
 */
17
18
namespace TYPO3\CMS\Install\SystemEnvironment\ServerResponse;
19
20
/**
21
 * Evaluates a Content-Security-Policy HTTP header.
22
 *
23
 * @internal should only be used from within TYPO3 Core
24
 */
25
class ContentSecurityPolicyHeader
26
{
27
    protected const HEADER_PATTERN = '#(?<directive>default-src|script-src|style-src|object-src)\h+(?<rule>[^;]+)(?:\s*;\s*|$)#';
28
29
    /**
30
     * @var ContentSecurityPolicyDirective[]
31
     */
32
    protected $directives = [];
33
34
    public function __construct(string $header)
35
    {
36
        if (preg_match_all(self::HEADER_PATTERN, $header, $matches)) {
37
            foreach ($matches['directive'] as $index => $name) {
38
                $this->directives[$name] = new ContentSecurityPolicyDirective(
39
                    $name,
40
                    $matches['rule'][$index]
41
                );
42
            }
43
        }
44
    }
45
46
    public function isEmpty(): bool
47
    {
48
        return empty($this->directives);
49
    }
50
51
    public function mitigatesCrossSiteScripting(): bool
52
    {
53
        $defaultSrc = isset($this->directives['default-src'])
54
            ? $this->directiveMitigatesCrossSiteScripting($this->directives['default-src'])
55
            : null;
56
        $scriptSrc = isset($this->directives['script-src'])
57
            ? $this->directiveMitigatesCrossSiteScripting($this->directives['script-src'])
58
            : null;
59
        $styleSrc = isset($this->directives['style-src'])
60
            ? $this->directiveMitigatesCrossSiteScripting($this->directives['style-src'])
61
            : null;
62
        $objectSrc = isset($this->directives['object-src'])
63
            ? $this->directiveMitigatesCrossSiteScripting($this->directives['object-src'])
64
            : null;
65
        return ($scriptSrc ?? $defaultSrc ?? false)
66
            && ($styleSrc ?? $defaultSrc ?? false)
67
            && ($objectSrc ?? $defaultSrc ?? false);
68
    }
69
70
    protected function directiveMitigatesCrossSiteScripting(ContentSecurityPolicyDirective $directive): bool
71
    {
72
        return $directive->hasInstructions('none')
73
            && !$directive->hasInstructions('unsafe-eval', 'unsafe-inline');
74
    }
75
}
76