Passed
Push — 2.x ( fa7f46...ac8b38 )
by Terry
02:13
created

XssProtectionTrait   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 147
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 50
c 2
b 0
f 0
dl 0
loc 147
rs 10
wmc 24

5 Methods

Rating   Name   Duplication   Size   Complexity  
A cleanCookie() 0 10 4
B cleanProtectedList() 0 28 9
A cleanGet() 0 10 4
A cleanPost() 0 10 4
A setupXssProtection() 0 16 3
1
<?php
2
/**
3
 * This file is part of the Shieldon package.
4
 *
5
 * (c) Terry L. <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 * 
10
 * php version 7.1.0
11
 * 
12
 * @category  Web-security
13
 * @package   Shieldon
14
 * @author    Terry Lin <[email protected]>
15
 * @copyright 2019 terrylinooo
16
 * @license   https://github.com/terrylinooo/shieldon/blob/2.x/LICENSE MIT
17
 * @link      https://github.com/terrylinooo/shieldon
18
 * @see       https://shieldon.io
19
 */
20
21
declare(strict_types=1);
22
23
namespace Shieldon\Firewall\Firewall;
24
25
use Shieldon\Security\Xss;
26
27
use function array_keys;
28
29
/*
30
 * Xss Protection Trait is loaded in Firewall instance only.
31
 */
32
trait XssProtectionTrait
33
{
34
    /**
35
     * Get options from the configuration file.
36
     * This method is same as `$this->getConfig()` but returning value from array directly.
37
     *
38
     * @param string $option  The option of the section in the the configuration.
39
     * @param string $section The section in the configuration.
40
     *
41
     * @return mixed
42
     */
43
    abstract protected function getOption(string $option, string $section = '');
44
45
    /**
46
     * Set up the XSS protection.
47
     *
48
     * @return void
49
     */
50
    protected function setupXssProtection(): void
51
    {
52
        $enable = $this->getOption('xss_protection');
53
        $protectedList = $this->getOption('xss_protected_list');
54
        $key = array_search(true, $enable);
55
56
        if (empty($key) && empty($protectedList)) {
57
            return;
58
        }
59
60
        $xss = new Xss();
61
62
        $this->cleanPost($enable, $xss);
63
        $this->cleanGet($enable, $xss);
64
        $this->cleanCookie($enable, $xss);
65
        $this->cleanProtectedList($protectedList, $xss);
66
    }
67
68
    /**
69
     * Clean the $_POST superglobal.
70
     *
71
     * @param array $enable The option to enable filtering $_POST.
72
     * @param Xss   $xss    The Xss instance.
73
     *
74
     * @return void
75
     */
76
    private function cleanPost(array $enable, Xss $xss): void
77
    {
78
        if ($enable['post']) {
79
80
            $this->kernel->setClosure(
81
                'xss_post',
82
                function () use ($xss) {
83
                    if (!empty($_POST)) {
84
                        foreach (array_keys($_POST) as $k) {
85
                            $_POST[$k] = $xss->clean($_POST[$k]);
86
                        }
87
                    }
88
                }
89
            );
90
        }
91
    }
92
93
    /**
94
     * Clean the $_GET superglobal.
95
     *
96
     * @param array $enable The option to enable filtering $_GET.
97
     * @param Xss   $xss    The Xss instance.
98
     *
99
     * @return void
100
     */
101
    private function cleanGet(array $enable, Xss $xss): void
102
    {
103
        if ($enable['get']) {
104
105
            $this->kernel->setClosure(
106
                'xss_get',
107
                function () use ($xss) {
108
                    if (!empty($_GET)) {
109
                        foreach (array_keys($_GET) as $k) {
110
                            $_GET[$k] = $xss->clean($_GET[$k]);
111
                        }
112
                    }
113
                }
114
            );
115
        }
116
    }
117
118
    /**
119
     * Clean the $_COOKIE superglobal.
120
     *
121
     * @param array $enable The option to enable filtering $_COOKIE.
122
     * @param Xss   $xss    The Xss instance.
123
     *
124
     * @return void
125
     */
126
    private function cleanCookie(array $enable, Xss $xss): void
127
    {
128
        if ($enable['cookie']) {
129
130
            $this->kernel->setClosure(
131
                'xss_cookie',
132
                function () use ($xss) {
133
                    if (!empty($_COOKIE)) {
134
                        foreach (array_keys($_COOKIE) as $k) {
135
                            $_COOKIE[$k] = $xss->clean($_COOKIE[$k]);
136
                        }
137
                    }
138
                }
139
            );
140
        }
141
    }
142
143
    /**
144
     * Clean the specific protected varibles.
145
     *
146
     * @param array $protectedList The specific variables to be filtered.
147
     * @param Xss   $xss           The Xss instance.
148
     *
149
     * @return void
150
     */
151
    private function cleanProtectedList(array $protectedList, Xss $xss): void
152
    {
153
        if (!empty($protectedList)) {
154
155
            $this->kernel->setClosure(
156
                'xss_protection', 
157
                function () use ($xss, $protectedList) {
158
                    foreach ($protectedList as $v) {
159
                        $k = $v['variable'] ?? 'undefined';
160
        
161
                        switch ($v['type']) {
162
                            case 'get':
163
                                if (!empty($_GET[$k])) {
164
                                    $_GET[$k] = $xss->clean($_GET[$k]);
165
                                }
166
                                break;
167
        
168
                            case 'post':
169
                                if (!empty($_POST[$k])) {
170
                                    $_POST[$k] = $xss->clean($_POST[$k]);
171
                                }
172
                                break;
173
        
174
                            case 'cookie':
175
                                if (!empty($_COOKIE[$k])) {
176
                                    $_COOKIE[$k] = $xss->clean($_COOKIE[$k]);
177
                                }
178
                                break;
179
                        }
180
                    }
181
                }
182
            );
183
        }
184
    }
185
}
186