Csp::sendHeader()   A
last analyzed

Complexity

Conditions 4
Paths 5

Size

Total Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 19
rs 9.6333
c 0
b 0
f 0
cc 4
nc 5
nop 0
1
<?php
2
/**
3
 * CSP
4
 *
5
 * @author     Kenji Suzuki <https://github.com/kenjis>
6
 * @license    MIT License
7
 * @copyright  2014 Kenji Suzuki
8
 * @link       https://github.com/kenjis/php-csp-nonce-source
9
 */
10
11
namespace Kenjis\Csp;
12
13
/**
14
 * CSP
15
 *
16
 * See http://www.w3.org/TR/CSP2/
17
 */
18
class Csp
19
{
20
    /**
21
     * @var \Kenjis\Csp\Nonce
22
     */
23
    private $nonce;
24
25
    private $policies = [];
26
27
    private $reportOnly = false;
28
29
    public function __construct(Nonce $nonce)
30
    {
31
        $this->nonce = $nonce;
32
    }
33
34
    /**
35
     * @param string $directive
36
     * @param string $value
37
     */
38
    public function addPolicy($directive, $value)
39
    {
40
        // with quotation
41
        $keywords = ['self', 'unsafe-inline', 'unsafe-eval', 'unsafe-redirect', 'none'];
42
        if (in_array($value, $keywords)) {
43
            $value = "'" . $value . "'";
44
        }
45
46
        $this->policies[$directive][] = $value;
47
        $tmp = array_unique($this->policies[$directive]);
48
        $this->policies[$directive] = $tmp;
49
    }
50
51
    public function getNonce()
52
    {
53
        return $this->nonce->getNonce();
54
    }
55
56
    public function setNonceSource()
57
    {
58
        $nonce = $this->nonce->getNonce();
59
        $value = "'" . 'nonce-' . $nonce . "'";
60
        $this->addPolicy('script-src', $value);
61
    }
62
63
    public function setReportOnly()
64
    {
65
        $this->reportOnly = true;
66
    }
67
68
    public function sendHeader()
69
    {
70
        $string = (string) $this;
71
72
        if ($string === '') {
73
            return;
74
        }
75
76
        if (! $this->reportOnly) {
77
            $fieldName = 'Content-Security-Policy';
78
        } else {
79
            $fieldName = 'Content-Security-Policy-Report-Only';
80
        }
81
82
        // Send CSP header only to browsers which supports nonce-source
83
        if ($this->nonce->getNonce() !== Nonce::UNSUPPORTED_BROWSER_NONCE) {
84
            header($fieldName . ': ' . $string);
85
        }
86
    }
87
88
    public function __toString()
89
    {
90
        $string = '';
91
        foreach ($this->policies as $directive => $values) {
92
            $string .= $directive . ' ' . implode(' ', $values) . '; ';
93
        }
94
95
        return rtrim($string, '; ');
96
    }
97
}
98