Issues (1844)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  Header Injection
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

assets/js/jpspan/JPSpan/Unserializer/XML.php (11 issues)

1
<?php declare(strict_types=1);
2
3
//---------------------------------------------------------------------------
4
5
/**
6
 * Handles parsing of XML requests
7
 */
8
class JPSpan_Unserializer_XML
9
{
10
    /**
11
     * Dictionary of tag names to data node classes
12
     * @var array
13
     */
14
    public $dict;
15
    /**
16
     * Node stack
17
     * @var array
18
     */
19
    public $stack;
20
    /**
21
     * Root node
22
     * @var JPSpan_Unserializer_XML_Root
23
     */
24
    public $root;
25
    /**
26
     * Instance of the SAX parser
27
     * @var int
28
     */
29
    public $parser;
30
    /**
31
     * Whether there's an error in parsing
32
     * @var bool (default = FALSE)
33
     */
34
    public $isError = false;
35
    /**
36
     * Switch for when we're inside the root node
37
     * @var bool
38
     */
39
    public $inData = false;
40
41
    /**
42
     * Set's up the dictionary
43
     */
44
    public function __construct()
45
    {
46
        $this->dict = [
47
            'r' => 'JPSpan_Unserializer_XML_Root',
48
            'n' => 'JPSpan_Unserializer_XML_Null',
49
            'b' => 'JPSpan_Unserializer_XML_Boolean',
50
            'i' => 'JPSpan_Unserializer_XML_Integer',
51
            'd' => 'JPSpan_Unserializer_XML_Double',
52
            's' => 'JPSpan_Unserializer_XML_String',
53
            'a' => 'JPSpan_Unserializer_XML_Array',
54
            'o' => 'JPSpan_Unserializer_XML_Object',
55
            'e' => 'JPSpan_Unserializer_XML_Element',
56
        ];
57
    }
58
59
    /**
60
     * Sax open tag callback
61
     * @param $parser
62
     * @param $tag
63
     * @param $attrs
64
     */
65
    public function open(&$parser, $tag, $attrs): void
66
    {
67
        if (!array_key_exists($tag, $this->dict)) {
68
            $errorMsg = 'Illegal tag name: ' . $tag;
69
            $this->raiseError($errorMsg);
70
71
            return;
72
        }
73
74
        if ('r' === $tag) {
75
            $this->inData = true;
76
        }
77
78
        if ($this->inData) {
79
            $class = $this->dict[$tag];
80
81
            $current       = new $class($this, $attrs);
82
            $this->stack[] = &$current;
83
84
            if ('r' === $tag) {
85
                $this->root = &$current;
86
            }
87
        }
88
    }
89
90
    /**
91
     * Sax tag cdata callback
92
     * @param $parser
93
     * @param $data
94
     */
95
    public function cdata(&$parser, $data): void
0 ignored issues
show
The parameter $parser is not used and could be removed. ( Ignorable by Annotation )

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

95
    public function cdata(/** @scrutinizer ignore-unused */ &$parser, $data): void

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
96
    {
97
        $len = count($this->stack);
98
        if ($this->stack[$len - 1]->isString) {
99
            $this->stack[$len - 1]->readString($data);
100
        }
101
    }
102
103
    /**
104
     * Sax close tag callback
105
     * @param $parser
106
     * @param $tag
107
     */
108
    public function close(&$parser, $tag): void
109
    {
110
        if ('r' === $tag) {
111
            $this->inData = false;
112
        }
113
114
        if ($this->inData) {
115
            $len = count($this->stack);
116
117
            $this->stack[$len - 2]->add($this->stack[$len - 1]);
118
119
            array_pop($this->stack);
120
        }
121
    }
122
123
    /**
124
     * Raise an error
125
     * @param mixed $msg
126
     */
127
    public function raiseError($msg): void
128
    {
129
        $this->isError = true;
130
        $msg           .= ' [byte index: ' . xml_get_current_byte_index($this->parser) . ']';
0 ignored issues
show
$this->parser of type integer is incompatible with the type XmlParser|resource expected by parameter $parser of xml_get_current_byte_index(). ( Ignorable by Annotation )

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

130
        $msg           .= ' [byte index: ' . xml_get_current_byte_index(/** @scrutinizer ignore-type */ $this->parser) . ']';
Loading history...
131
        trigger_error($msg, E_USER_ERROR);
132
    }
133
134
    /**
135
     * Unserialize some XML. If the provided param is not a string containing
136
     * an XML document, it will be returned as is
137
     * @param mixed $data
138
     * @return mixed unserialized data structure
139
     */
140
    public function unserialize($data)
141
    {
142
        // Return anything that's not XML immediately
143
        if (!is_string($data) || !preg_match('/^\s*<\?xml(.+)\?>/U', $data, $match)) {
144
            return $data;
145
        }
146
147
        $this->parser = xml_parser_create('UTF-8');
0 ignored issues
show
Documentation Bug introduced by
It seems like xml_parser_create('UTF-8') of type XmlParser or resource is incompatible with the declared type integer of property $parser.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
148
        xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, false);
149
        xml_set_object($this->parser, $this);
150
        xml_set_elementHandler($this->parser, 'open', 'close');
0 ignored issues
show
The function xml_set_elementHandler was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

150
        /** @scrutinizer ignore-call */ 
151
        xml_set_elementHandler($this->parser, 'open', 'close');
Loading history...
151
        xml_set_character_dataHandler($this->parser, 'cdata');
0 ignored issues
show
The function xml_set_character_dataHandler was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

151
        /** @scrutinizer ignore-call */ 
152
        xml_set_character_dataHandler($this->parser, 'cdata');
Loading history...
152
153
        if (!xml_parse($this->parser, trim($data), true)) {
154
            $errorCode = xml_get_error_code($this->parser);
155
            $errorMsg  = 'Badly formed XML: (' . $errorCode . ') ' . xml_error_string($this->parser);
0 ignored issues
show
$this->parser of type XmlParser|resource is incompatible with the type integer expected by parameter $error_code of xml_error_string(). ( Ignorable by Annotation )

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

155
            $errorMsg  = 'Badly formed XML: (' . $errorCode . ') ' . xml_error_string(/** @scrutinizer ignore-type */ $this->parser);
Loading history...
156
            $this->raiseError($errorMsg);
157
        }
158
159
        @xml_parser_free($this->parser);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for xml_parser_free(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

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

159
        /** @scrutinizer ignore-unhandled */ @xml_parser_free($this->parser);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
160
161
        if (!$this->isError) {
162
            return $this->root->value;
163
        }
164
165
        return false;
166
    }
167
}
168
169
//---------------------------------------------------------------------------
170
171
/**
172
 * Base class for represented data elements in XML
173
 */
174
class JPSpan_Unserializer_XML_Node
175
{
176
    /**
177
     * @var JPSpan_Unserializer_XML
178
     */
179
    public $Handler;
180
    /**
181
     * @var mixed node value
182
     */
183
    public $value;
184
    /**
185
     * @var bool switch to indentify JPSpan_Unserializer_XML_Element nodes
186
     */
187
    public $isElement = false;
188
    /**
189
     * @var bool switch to identify JPSpan_Unserializer_XML_String nodes
190
     */
191
    public $isString = false;
192
193
    /**
194
     * @param mixed $Handler
195
     */
196
    public function __construct(&$Handler)
197
    {
198
        $this->Handler = &$Handler;
199
    }
200
201
    /**
202
     * @param mixed $child
203
     */
204
    public function add($child): void
205
    {
206
        $errorMsg = 'Scalar nodes cannot have children';
207
        $this->Handler->raiseError($errorMsg);
208
    }
209
}
210
211
//---------------------------------------------------------------------------
212
213
/**
214
 * The root XML tag 'r'. Zero or one child tag allowed
215
 */
216
class JPSpan_Unserializer_XML_Root extends JPSpan_Unserializer_XML_Node
217
{
218
    /**
219
     * Switch to track whether root as single child node
220
     * @var bool
221
     */
222
    public $hasValue = false;
223
224
    /**
225
     * @param mixed $Handler
226
     * @param mixed $attrs
227
     */
228
    public function __construct(&$Handler, $attrs)
0 ignored issues
show
The parameter $attrs is not used and could be removed. ( Ignorable by Annotation )

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

228
    public function __construct(&$Handler, /** @scrutinizer ignore-unused */ $attrs)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
229
    {
230
        $this->Handler = &$Handler;
231
        $this->value   = null;
232
    }
233
234
    /**
235
     * @param mixed $child
236
     */
237
    public function add($child): void
238
    {
239
        if ($this->hasValue) {
240
            $errorMsg = 'Root node can only contain a single child node';
241
            $this->Handler->raiseError($errorMsg);
242
        } else {
243
            if (!$child->isElement) {
244
                $this->value    = $child->value;
245
                $this->hasValue = true;
246
            } else {
247
                $errorMsg = 'Element nodes can only be placed inside array or object nodes';
248
                $this->Handler->raiseError($errorMsg);
249
            }
250
        }
251
    }
252
}
253
254
//---------------------------------------------------------------------------
255
256
/**
257
 * Null variable 'n'. No children allowed
258
 */
259
class JPSpan_Unserializer_XML_Null extends JPSpan_Unserializer_XML_Node
260
{
261
    /**
262
     * @param mixed $Handler
263
     * @param mixed $attrs
264
     */
265
    public function __construct(&$Handler, $attrs)
0 ignored issues
show
The parameter $attrs is not used and could be removed. ( Ignorable by Annotation )

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

265
    public function __construct(&$Handler, /** @scrutinizer ignore-unused */ $attrs)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
266
    {
267
        $this->Handler = &$Handler;
268
        $this->value   = null;
269
    }
270
}
271
272
//---------------------------------------------------------------------------
273
274
/**
275
 * Boolean variable 'b'. Attribute 'v' required. No children allowed
276
 */
277
class JPSpan_Unserializer_XML_Boolean extends JPSpan_Unserializer_XML_Node
278
{
279
    /**
280
     * @param mixed $Handler
281
     * @param mixed $attrs
282
     */
283
    public function __construct(&$Handler, $attrs)
284
    {
285
        $this->Handler = &$Handler;
286
287
        if (isset($attrs['v'])) {
288
            $this->value = (bool)$attrs['v'];
289
        } else {
290
            $errorMsg = 'Value required for boolean';
291
            $this->Handler->raiseError($errorMsg);
292
        }
293
    }
294
}
295
296
//---------------------------------------------------------------------------
297
298
/**
299
 * Integer variable 'i'. Attribute 'v' required. No children allowed
300
 */
301
class JPSpan_Unserializer_XML_Integer extends JPSpan_Unserializer_XML_Node
302
{
303
    /**
304
     * @param mixed $Handler
305
     * @param mixed $attrs
306
     */
307
    public function __construct(&$Handler, $attrs)
308
    {
309
        $this->Handler = &$Handler;
310
311
        if (isset($attrs['v'])) {
312
            $this->value = (int)$attrs['v'];
313
        } else {
314
            $errorMsg = 'Value required for integer';
315
            $this->Handler->raiseError($errorMsg);
316
        }
317
    }
318
}
319
320
//---------------------------------------------------------------------------
321
322
/**
323
 * Double variable 'd' - 'v' attribute required. No children allowed
324
 */
325
class JPSpan_Unserializer_XML_Double extends JPSpan_Unserializer_XML_Node
326
{
327
    /**
328
     * @param mixed $Handler
329
     * @param mixed $attrs
330
     */
331
    public function __construct(&$Handler, $attrs)
332
    {
333
        $this->Handler = &$Handler;
334
335
        if (isset($attrs['v'])) {
336
            $this->value = (float)$attrs['v'];
337
        } else {
338
            $errorMsg = 'Value required for double';
339
            $this->Handler->raiseError($errorMsg);
340
        }
341
    }
342
}
343
344
//---------------------------------------------------------------------------
345
346
/**
347
 * String variable 's' - value passed from JPSpan_Unserializer_XML::cdata
348
 * No child tags allowed
349
 */
350
class JPSpan_Unserializer_XML_String extends JPSpan_Unserializer_XML_Node
351
{
352
    /**
353
     * Declare it's a string - instructs JPSpan_Unserializer_XML::cdata to
354
     * pass on string values
355
     * @var bool TRUE
356
     */
357
    public $isString = true;
358
359
    /**
360
     * @param mixed $Handler
361
     * @param mixed $attrs
362
     */
363
    public function __construct(&$Handler, $attrs)
0 ignored issues
show
The parameter $attrs is not used and could be removed. ( Ignorable by Annotation )

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

363
    public function __construct(&$Handler, /** @scrutinizer ignore-unused */ $attrs)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
364
    {
365
        $this->Handler = &$Handler;
366
        $this->value   = '';
367
    }
368
369
    /**
370
     * Read some more string
371
     * @param mixed $string
372
     */
373
    public function readString($string): void
374
    {
375
        $this->value .= $string;
376
    }
377
}
378
379
//---------------------------------------------------------------------------
380
381
/**
382
 * Array variable 'a' - can only contain 'e' tags - zero or more
383
 */
384
class JPSpan_Unserializer_XML_Array extends JPSpan_Unserializer_XML_Node
385
{
386
    /**
387
     * @param mixed $Handler
388
     * @param mixed $attrs
389
     */
390
    public function __construct(&$Handler, $attrs)
0 ignored issues
show
The parameter $attrs is not used and could be removed. ( Ignorable by Annotation )

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

390
    public function __construct(&$Handler, /** @scrutinizer ignore-unused */ $attrs)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
391
    {
392
        $this->Handler = &$Handler;
393
        $this->value   = [];
394
    }
395
396
    /**
397
     * @param mixed $child
398
     */
399
    public function add($child): void
400
    {
401
        if ($child->isElement && null !== $child->key) {
402
            $this->value[$child->key] = $child->value;
403
        } else {
404
            $errorMsg = 'Array nodes can only contain element nodes';
405
            $this->Handler->raiseError($errorMsg);
406
        }
407
    }
408
}
409
410
//---------------------------------------------------------------------------
411
412
/**
413
 * Object variable 'o'. Attribute 'c' (class name) required
414
 * Can only contain 'e' tags - zero or more
415
 */
416
class JPSpan_Unserializer_XML_Object extends JPSpan_Unserializer_XML_Node
417
{
418
    /**
419
     * @param mixed $Handler
420
     * @param mixed $attrs
421
     */
422
    public function __construct(&$Handler, $attrs)
423
    {
424
        $this->Handler = &$Handler;
425
426
        if (isset($attrs['c'])) {
427
            $class = $attrs['c'];
428
429
            if (!array_key_exists(mb_strtolower($class), $GLOBALS['_JPSPAN_UNSERIALIZER_MAP'])) {
430
                $errorMsg = 'Illegal object type: ' . \mb_strtolower($class);
431
                $this->Handler->raiseError($errorMsg);
432
433
                return;
434
            }
435
436
            $this->value = new $class();
437
        } else {
438
            $errorMsg = 'Object node requires class attribute';
439
            $this->Handler->raiseError($errorMsg);
440
        }
441
    }
442
443
    /**
444
     * @param mixed $child
445
     */
446
    public function add($child): void
447
    {
448
        if ($child->isElement && $child->key) {
449
            $this->value->{$child->key} = $child->value;
450
        } else {
451
            $errorMsg = 'Object nodes can only contain element nodes';
452
            $this->Handler->raiseError($errorMsg);
453
        }
454
    }
455
}
456
457
//---------------------------------------------------------------------------
458
459
/**
460
 * Array element or object property variable 'e'. Attribute 'k' (key) required
461
 * Can contain zero or one child tags
462
 */
463
class JPSpan_Unserializer_XML_Element extends JPSpan_Unserializer_XML_Node
464
{
465
    /**
466
     * Value of element - defaults to NULL if no child
467
     * @var mixed value
468
     */
469
    public $value = null;
470
    /**
471
     * Element key (e.g. array index or object property name)
472
     * @var mixed key (string or integer)
473
     */
474
    public $key = null;
475
    /**
476
     * Declare it's an element
477
     * @var bool TRUE
478
     */
479
    public $isElement = true;
480
481
    /**
482
     * @param mixed $Handler
483
     * @param mixed $attrs
484
     */
485
    public function __construct(&$Handler, $attrs)
486
    {
487
        $this->Handler = &$Handler;
488
489
        if (isset($attrs['k'])) {
490
            $this->key = $attrs['k'];
491
        } else {
492
            $errorMsg = 'Element node requires key attribute';
493
            $this->Handler->raiseError($errorMsg);
494
        }
495
    }
496
497
    /**
498
     * @param mixed $child
499
     */
500
    public function add($child): void
501
    {
502
        if ($child->isElement) {
503
            $errorMsg = 'Element nodes can only be placed inside array or object nodes';
504
            $this->Handler->raiseError($errorMsg);
505
        } else {
506
            $this->value = $child->value;
507
        }
508
    }
509
}
510