Completed
Push — master ( e96f63...7cd0ea )
by Rob
02:01
created

NeverAllowed::doNeverAllowed()   A

Complexity

Conditions 5
Paths 12

Size

Total Lines 37

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 24
CRAP Score 5

Importance

Changes 0
Metric Value
dl 0
loc 37
ccs 24
cts 24
cp 1
rs 9.0168
c 0
b 0
f 0
cc 5
nc 12
nop 1
crap 5
1
<?php
2
3
namespace devtoolboxuk\soteria\voku\Resources;
4
5
class NeverAllowed extends Resources
0 ignored issues
show
Coding Style introduced by
The property $_never_allowed_reg_ex is not named in camelCase.

This check marks property names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
Coding Style introduced by
The property $_never_allowed_on_events_afterwards is not named in camelCase.

This check marks property names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
Coding Style introduced by
The property $_never_allowed_str_afterwards is not named in camelCase.

This check marks property names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
Coding Style introduced by
The property $_never_allowed_call_statements is not named in camelCase.

This check marks property names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
6
{
7
8
    private $_never_allowed_reg_ex = [
9
10
        // default javascript
11
        '(\(?document\)?|\(?window\)?(\.document)?)\.(location|on\w*)',
12
        // data-attribute + base64
13
        "([\"'])?data\s*:[^\\1]*?base64[^\\1]*?,[^\\1]*?\\1?",
14
        // remove Netscape 4 JS entities
15
        '&\s*\{[^}]*(\}\s*;?|$)',
16
        // old IE, old Netscape
17
        'expression\s*(\(|&\#40;)',
18
    ];
19
20
    private $_never_allowed_on_events_afterwards = [
21
        'onAbort',
22
        'onActivate',
23
        'onAttribute',
24
        'onAfterPrint',
25
        'onAfterScriptExecute',
26
        'onAfterUpdate',
27
        'onAnimationCancel',
28
        'onAnimationEnd',
29
        'onAnimationIteration',
30
        'onAnimationStart',
31
        'onAriaRequest',
32
        'onAutoComplete',
33
        'onAutoCompleteError',
34
        'onAuxClick',
35
        'onBeforeActivate',
36
        'onBeforeCopy',
37
        'onBeforeCut',
38
        'onBeforeDeactivate',
39
        'onBeforeEditFocus',
40
        'onBeforePaste',
41
        'onBeforePrint',
42
        'onBeforeScriptExecute',
43
        'onBeforeUnload',
44
        'onBeforeUpdate',
45
        'onBegin',
46
        'onBlur',
47
        'onBounce',
48
        'onCancel',
49
        'onCanPlay',
50
        'onCanPlayThrough',
51
        'onCellChange',
52
        'onChange',
53
        'onClick',
54
        'onClose',
55
        'onCommand',
56
        'onCompassNeedsCalibration',
57
        'onContextMenu',
58
        'onControlSelect',
59
        'onCopy',
60
        'onCueChange',
61
        'onCut',
62
        'onDataAvailable',
63
        'onDataSetChanged',
64
        'onDataSetComplete',
65
        'onDblClick',
66
        'onDeactivate',
67
        'onDeviceLight',
68
        'onDeviceMotion',
69
        'onDeviceOrientation',
70
        'onDeviceProximity',
71
        'onDrag',
72
        'onDragDrop',
73
        'onDragEnd',
74
        'onDragEnter',
75
        'onDragLeave',
76
        'onDragOver',
77
        'onDragStart',
78
        'onDrop',
79
        'onDurationChange',
80
        'onEmptied',
81
        'onEnd',
82
        'onEnded',
83
        'onError',
84
        'onErrorUpdate',
85
        'onExit',
86
        'onFilterChange',
87
        'onFinish',
88
        'onFocus',
89
        'onFocusIn',
90
        'onFocusOut',
91
        'onFormChange',
92
        'onFormInput',
93
        'onFullScreenChange',
94
        'onFullScreenError',
95
        'onGotPointerCapture',
96
        'onHashChange',
97
        'onHelp',
98
        'onInput',
99
        'onInvalid',
100
        'onKeyDown',
101
        'onKeyPress',
102
        'onKeyUp',
103
        'onLanguageChange',
104
        'onLayoutComplete',
105
        'onLoad',
106
        'onLoadedData',
107
        'onLoadedMetaData',
108
        'onLoadStart',
109
        'onLoseCapture',
110
        'onLostPointerCapture',
111
        'onMediaComplete',
112
        'onMediaError',
113
        'onMessage',
114
        'onMouseDown',
115
        'onMouseEnter',
116
        'onMouseLeave',
117
        'onMouseMove',
118
        'onMouseOut',
119
        'onMouseOver',
120
        'onMouseUp',
121
        'onMouseWheel',
122
        'onMove',
123
        'onMoveEnd',
124
        'onMoveStart',
125
        'onMozFullScreenChange',
126
        'onMozFullScreenError',
127
        'onMozPointerLockChange',
128
        'onMozPointerLockError',
129
        'onMsContentZoom',
130
        'onMsFullScreenChange',
131
        'onMsFullScreenError',
132
        'onMsGestureChange',
133
        'onMsGestureDoubleTap',
134
        'onMsGestureEnd',
135
        'onMsGestureHold',
136
        'onMsGestureStart',
137
        'onMsGestureTap',
138
        'onMsGotPointerCapture',
139
        'onMsInertiaStart',
140
        'onMsLostPointerCapture',
141
        'onMsManipulationStateChanged',
142
        'onMsPointerCancel',
143
        'onMsPointerDown',
144
        'onMsPointerEnter',
145
        'onMsPointerLeave',
146
        'onMsPointerMove',
147
        'onMsPointerOut',
148
        'onMsPointerOver',
149
        'onMsPointerUp',
150
        'onMsSiteModeJumpListItemRemoved',
151
        'onMsThumbnailClick',
152
        'onOffline',
153
        'onOnline',
154
        'onOutOfSync',
155
        'onPage',
156
        'onPageHide',
157
        'onPageShow',
158
        'onPaste',
159
        'onPause',
160
        'onPlay',
161
        'onPlaying',
162
        'onPointerCancel',
163
        'onPointerDown',
164
        'onPointerEnter',
165
        'onPointerLeave',
166
        'onPointerLockChange',
167
        'onPointerLockError',
168
        'onPointerMove',
169
        'onPointerOut',
170
        'onPointerOver',
171
        'onPointerUp',
172
        'onPopState',
173
        'onProgress',
174
        'onPropertyChange',
175
        'onRateChange',
176
        'onReadyStateChange',
177
        'onReceived',
178
        'onRepeat',
179
        'onReset',
180
        'onResize',
181
        'onResizeEnd',
182
        'onResizeStart',
183
        'onResume',
184
        'onReverse',
185
        'onRowDelete',
186
        'onRowEnter',
187
        'onRowExit',
188
        'onRowInserted',
189
        'onRowsDelete',
190
        'onRowsEnter',
191
        'onRowsExit',
192
        'onRowsInserted',
193
        'onScroll',
194
        'onSearch',
195
        'onSeek',
196
        'onSeeked',
197
        'onSeeking',
198
        'onSelect',
199
        'onSelectionChange',
200
        'onSelectStart',
201
        'onStalled',
202
        'onStorage',
203
        'onStorageCommit',
204
        'onStart',
205
        'onStop',
206
        'onShow',
207
        'onSyncRestored',
208
        'onSubmit',
209
        'onSuspend',
210
        'onSynchRestored',
211
        'onTimeError',
212
        'onTimeUpdate',
213
        'onTrackChange',
214
        'onTransitionEnd',
215
        'onToggle',
216
        'onTouchCancel',
217
        'onTouchStart',
218
        'onTransitionCancel',
219
        'onTransitionEnd',
220
        'onUnload',
221
        'onURLFlip',
222
        'onUserProximity',
223
        'onVolumeChange',
224
        'onWaiting',
225
        'onWebKitAnimationEnd',
226
        'onWebKitAnimationIteration',
227
        'onWebKitAnimationStart',
228
        'onWebKitFullScreenChange',
229
        'onWebKitFullScreenError',
230
        'onWebKitTransitionEnd',
231
        'onWheel',
232
    ];
233
234
    private $_never_allowed_str_afterwards = [
235
        'FSCOMMAND',
236
        '&lt;script&gt;',
237
        '&lt;/script&gt;',
238
    ];
239
    
240
    private $_never_allowed_call_statements = [
241
        // default javascript
242
        'javascript',
243
        // Java: jar-protocol is an XSS hazard
244
        'jar',
245
        // Mac (will not run the script, but open it in AppleScript Editor)
246
        'applescript',
247
        // IE: https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet#VBscript_in_an_image
248
        'vbscript',
249
        'vbs',
250
        // IE, surprise!
251
        'wscript',
252
        // IE
253
        'jscript',
254
        // https://html5sec.org/#behavior
255
        'behavior',
256
        // old Netscape
257
        'mocha',
258
        // old Netscape
259
        'livescript',
260
        // default view source
261
        'view-source',
262
    ];
263
264 6
    public function doNeverAllowedAfterwards($str)
0 ignored issues
show
Coding Style Naming introduced by
The variable $temp_count is not named in camelCase.

This check marks variable names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
265
    {
266 6
        if (stripos($str, 'on') !== false) {
267 6
            foreach ($this->_never_allowed_on_events_afterwards as $event) {
268 6
                if (stripos($str, $event) !== false) {
269 2
                    $regex = '(?<before>[^\p{L}]|^)(?:' . $event . ')(?<after>\s|[^\p{L}]|$)';
270
271
                    do {
272 2
                        $count = $temp_count = 0;
273
274 2
                        $str = (string)\preg_replace(
275 2
                            '#' . $regex . '#ius',
276 2
                            '$1' . $this->_replacement . '$2',
277 2
                            $str,
278 2
                            -1,
279
                            $temp_count
280 2
                        );
281 2
                        $count += $temp_count;
282 2
                    } while ($count);
283 2
                }
284 6
            }
285 6
        }
286
287 6
        return (string)str_ireplace(
288 6
            $this->_never_allowed_str_afterwards,
289 6
            $this->_replacement,
290
            $str
291 6
        );
292
    }
293
294 6
    public function doNeverAllowed($str)
0 ignored issues
show
Coding Style Naming introduced by
The variable $NEVER_ALLOWED_CACHE is not named in camelCase.

This check marks variable names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
Complexity introduced by
This operation has 12 execution paths which exceeds the configured maximum of 10.

A high number of execution paths generally suggests many nested conditional statements and make the code less readible. This can usually be fixed by splitting the method into several smaller methods.

You can also find more information in the “Code” section of your repository.

Loading history...
295
    {
296 6
        static $NEVER_ALLOWED_CACHE = [];
297
298 6
        $NEVER_ALLOWED_CACHE['keys'] = null;
299 6
        $NEVER_ALLOWED_CACHE['regex'] = null;
300
301 6
        if ($NEVER_ALLOWED_CACHE['keys'] === null) {
302 6
            $NEVER_ALLOWED_CACHE['keys'] = array_keys($this->neverAllowedStrings());
303 6
        }
304
305 6
        $str = str_ireplace(
306 6
            $NEVER_ALLOWED_CACHE['keys'],
307 6
            $this->neverAllowedStrings(),
308
            $str
309 6
        );
310
311
312 6
        foreach ($this->_never_allowed_call_statements as $call) {
313 6
            if (stripos($str, $call) !== false) {
314 6
                $str = (string)preg_replace(
315 6
                    '#([^\p{L}]|^)' . $call . '\s*:#ius',
316 6
                    '$1' . $this->_replacement,
317
                    $str
318 6
                );
319 6
            }
320 6
        }
321
322
323 6
        if ($NEVER_ALLOWED_CACHE['regex'] === null) {
324 6
            $NEVER_ALLOWED_CACHE['regex'] = implode('|', $this->_never_allowed_reg_ex);
325 6
        }
326
327 6
        $str = (string)preg_replace('#' . $NEVER_ALLOWED_CACHE['regex'] . '#ius', $this->_replacement, $str);
328
329 6
        return $str;
330
    }
331
332 6
    private function neverAllowedStrings()
333
    {
334
        return [
335 6
            'document.cookie' => $this->_replacement,
336 6
            '(document).cookie' => $this->_replacement,
337 6
            'document.write' => $this->_replacement,
338 6
            '(document).write' => $this->_replacement,
339 6
            '.parentNode' => $this->_replacement,
340 6
            '.innerHTML' => $this->_replacement,
341 6
            '.appendChild' => $this->_replacement,
342 6
            '-moz-binding' => $this->_replacement,
343 6
            '<!--' => '&lt;!--',
344 6
            '-->' => '--&gt;',
345 6
            '<?' => '&lt;?',
346 6
            '?>' => '?&gt;',
347 6
            '<![CDATA[' => '&lt;![CDATA[',
348 6
            '<!ENTITY' => '&lt;!ENTITY',
349 6
            '<!DOCTYPE' => '&lt;!DOCTYPE',
350 6
            '<!ATTLIST' => '&lt;!ATTLIST',
351 6
        ];
352
    }
353
}