Passed
Push — 2.x ( a336cc...b20143 )
by Terry
01:59
created

XssProtectionTrait::cleanProtectedList()   B

Complexity

Conditions 9
Paths 2

Size

Total Lines 26
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 18
nc 2
nop 2
dl 0
loc 26
rs 8.0555
c 0
b 0
f 0
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
11
declare(strict_types=1);
12
13
namespace Shieldon\Firewall\Traits\Firewall;
14
15
use Shieldon\Firewall\Security\Xss;
16
17
use function array_keys;
18
19
/*
20
 * Xss Protection Trait is loaded in Firewall instance only.
21
 */
22
trait XssProtectionTrait
23
{
24
    /**
25
     * Fetch value from configuration.
26
     *
27
     * @return array|bool|string
28
     */
29
    abstract function getOption();
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
30
31
    /**
32
     * Set XSS protection.
33
     *
34
     * @return void
35
     */
36
    protected function setXssProtection(): void
37
    {
38
        $enable = $this->getOption('xss_protection');
0 ignored issues
show
Unused Code introduced by
The call to Shieldon\Firewall\Traits...ctionTrait::getOption() has too many arguments starting with 'xss_protection'. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

38
        /** @scrutinizer ignore-call */ 
39
        $enable = $this->getOption('xss_protection');

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
39
        $protectedList = $this->getOption('xss_protected_list');
40
        $key = array_search(true, $enable);
0 ignored issues
show
Bug introduced by
It seems like $enable can also be of type boolean and string; however, parameter $haystack of array_search() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

40
        $key = array_search(true, /** @scrutinizer ignore-type */ $enable);
Loading history...
41
42
        if (empty($key) && empty($protectedList)) {
43
            return;
44
        }
45
46
        $xss = new Xss();
47
48
        $this->cleanPost($enable, $xss);
0 ignored issues
show
Bug introduced by
It seems like $enable can also be of type boolean and string; however, parameter $enable of Shieldon\Firewall\Traits...ctionTrait::cleanPost() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

48
        $this->cleanPost(/** @scrutinizer ignore-type */ $enable, $xss);
Loading history...
49
        $this->cleanGet($enable, $xss);
0 ignored issues
show
Bug introduced by
It seems like $enable can also be of type boolean and string; however, parameter $enable of Shieldon\Firewall\Traits...ectionTrait::cleanGet() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

49
        $this->cleanGet(/** @scrutinizer ignore-type */ $enable, $xss);
Loading history...
50
        $this->cleanCookie($enable, $xss);
0 ignored issues
show
Bug introduced by
It seems like $enable can also be of type boolean and string; however, parameter $enable of Shieldon\Firewall\Traits...ionTrait::cleanCookie() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

50
        $this->cleanCookie(/** @scrutinizer ignore-type */ $enable, $xss);
Loading history...
51
        $this->cleanProtectedList($protectedList, $xss);
0 ignored issues
show
Bug introduced by
It seems like $protectedList can also be of type boolean and string; however, parameter $protectedList of Shieldon\Firewall\Traits...t::cleanProtectedList() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

51
        $this->cleanProtectedList(/** @scrutinizer ignore-type */ $protectedList, $xss);
Loading history...
52
    }
53
54
    /**
55
     * Clean the $_POST superglobal.
56
     *
57
     * @param array $enable
58
     * @param Xss   $xss
59
     *
60
     * @return void
61
     */
62
    private function cleanPost(array $enable, Xss $xss): void
63
    {
64
        if ($enable['post']) {
65
            $this->kernel->setClosure('xss_post', function() use ($xss) {
66
                if (!empty($_POST)) {
67
                    foreach (array_keys($_POST) as $k) {
68
                        $_POST[$k] = $xss->clean($_POST[$k]);
69
                    }
70
                }
71
            });
72
        }
73
    }
74
75
    /**
76
     * Clean the $_GET superglobal.
77
     *
78
     * @param array $enable
79
     * @param Xss   $xss
80
     *
81
     * @return void
82
     */
83
    private function cleanGet(array $enable, Xss $xss): void
84
    {
85
        if ($enable['get']) {
86
            $this->kernel->setClosure('xss_get', function() use ($xss) {
87
                if (!empty($_GET)) {
88
                    foreach (array_keys($_GET) as $k) {
89
                        $_GET[$k] = $xss->clean($_GET[$k]);
90
                    }
91
                }
92
            });
93
        }
94
    }
95
96
    /**
97
     * Clean the $_COOKIE superglobal.
98
     *
99
     * @param array $enable
100
     * @param Xss   $xss
101
     *
102
     * @return void
103
     */
104
    private function cleanCookie(array $enable, Xss $xss): void
105
    {
106
        if ($enable['cookie']) {
107
            $this->kernel->setClosure('xss_cookie', function() use ($xss) {
108
                if (!empty($_COOKIE)) {
109
                    foreach (array_keys($_COOKIE) as $k) {
110
                        $_COOKIE[$k] = $xss->clean($_COOKIE[$k]);
111
                    }
112
                }
113
            });
114
        }
115
    }
116
117
    /**
118
     * Clean the specific protected varibles.
119
     *
120
     * @param array $protectedLis
121
     * @param Xss   $xss
122
     *
123
     * @return void
124
     */
125
    private function cleanProtectedList(array $protectedList, Xss $xss): void
126
    {
127
        if (!empty($protectedList)) {
128
            $this->kernel->setClosure('xss_protection', 
129
                function() use ($xss, $protectedList) {
130
                    foreach ($protectedList as $v) {
131
                        $k = $v['variable'] ?? 'undefined';
132
        
133
                        switch ($v['type']) {
134
                            case 'get':
135
                                if (!empty($_GET[$k])) {
136
                                    $_GET[$k] = $xss->clean($_GET[$k]);
137
                                }
138
                                break;
139
        
140
                            case 'post':
141
                                if (!empty($_POST[$k])) {
142
                                    $_POST[$k] = $xss->clean($_POST[$k]);
143
                                }
144
                                break;
145
        
146
                            case 'cookie':
147
                                if (!empty($_COOKIE[$k])) {
148
                                    $_COOKIE[$k] = $xss->clean($_COOKIE[$k]);
149
                                }
150
                                break;
151
                        }
152
                    }
153
                }
154
            );
155
        }
156
    }
157
}
158