Issues (212)

Security Analysis    not enabled

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

  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.
  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.
  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.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  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.
  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.
  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.
  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.
  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.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  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.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
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.

class/Utility.php (4 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php namespace XoopsModules\Planet;
2
3
//
4
// ------------------------------------------------------------------------ //
5
// This program is free software; you can redistribute it and/or modify     //
6
// it under the terms of the GNU General Public License as published by     //
7
// the Free Software Foundation; either version 2 of the License, or        //
8
// (at your option) any later version.                                      //
9
//                                                                          //
10
// You may not change or alter any portion of this comment or credits       //
11
// of supporting developers from this source code or any supporting         //
12
// source code which is considered copyrighted (c) material of the          //
13
// original comment or credit authors.                                      //
14
//                                                                          //
15
// This program is distributed in the hope that it will be useful,          //
16
// but WITHOUT ANY WARRANTY; without even the implied warranty of           //
17
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            //
18
// GNU General Public License for more details.                             //
19
//                                                                          //
20
// You should have received a copy of the GNU General Public License        //
21
// along with this program; if not, write to the Free Software              //
22
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA //
23
// ------------------------------------------------------------------------ //
24
// Author: phppp (D.J., [email protected])                                  //
25
// URL: https://xoops.org                         //
26
// Project: Article Project                                                 //
27
// ------------------------------------------------------------------------ //
28
use Xmf\Request;
29
use XoopsModules\Planet;
30
/** @var Planet\Helper $helper */
31
$helper = Planet\Helper::getInstance();
32
33
// defined('XOOPS_ROOT_PATH') || die('Restricted access');
34
35
$current_path = __FILE__;
36 View Code Duplication
if (DIRECTORY_SEPARATOR !== '/') {
37
    $current_path = str_replace(strpos($current_path, '\\\\', 2) ? '\\\\' : DIRECTORY_SEPARATOR, '/', $current_path);
38
}
39
$url_arr               = explode('/', strstr($current_path, '/modules/'));
40
$GLOBALS['moddirname'] = $url_arr[2];
41
42
if (!defined('planet_FUNCTIONS')):
43
    define('planet_FUNCTIONS', 1);
44
45
    require XOOPS_ROOT_PATH . '/modules/' . $GLOBALS['moddirname'] . '/include/vars.php';
46
    require_once XOOPS_ROOT_PATH . '/class/xoopslists.php';
47
    require_once XOOPS_ROOT_PATH . '/Frameworks/art/functions.php';
48
49
    /**
50
     * Class Utility
51
     */
52
    class Utility
53
    {
54
55
        /**
56
         * Function to display messages
57
         *
58
         * @var mixed $messages
59
         * @return bool
60
         */
61
        public static function planetDisplayMessage($message)
62
        {
63
            return mod_message($message);
64
        }
65
66
        /**
67
         * Function to parse arguments for a page according to $_SERVER['REQUEST_URI']
68
         *
69
         * @var array $args_numeric array of numeric variable values
70
         * @var array $args         array of indexed variables: name and value
71
         * @var array $args_string  array of string variable values
72
         *
73
         * @return bool true on args parsed
74
         */
75
76
        /* known issues:
77
         * - "/" in a string
78
         * - "&" in a string
79
        */
80 View Code Duplication
        public static function planetParseArguments(&$args_numeric, &$args, &$args_string)
81
        {
82
            $args_abb     = [
83
                'a' => 'article',
84
                'b' => 'blog',
85
                'c' => 'category',
86
                'l' => 'list',
87
                'o' => 'sort',
88
                's' => 'start',
89
                'u' => 'uid'
90
            ];
91
            $args         = [];
92
            $args_numeric = [];
93
            $args_string  = [];
94
            if (preg_match("/[^\?]*\.php[\/|\?]([^\?]*)/i", Request::getUrl('REQUEST_URI', '', 'SERVER'), $matches)) {
95
                $vars = preg_split("/[\/|&]/", $matches[1]);
96
                $vars = array_map('trim', $vars);
97
                if (count($vars) > 0) {
98
                    foreach ($vars as $var) {
99
                        if (is_numeric($var)) {
100
                            $args_numeric[] = $var;
101
                        } elseif (false === strpos($var, '=')) {
102
                            if (is_numeric(substr($var, 1))) {
103
                                $args[$args_abb[strtolower($var{0})]] = (int)substr($var, 1);
104
                            } else {
105
                                $args_string[] = urldecode($var);
106
                            }
107
                        } else {
108
                            parse_str($var, $args);
109
                        }
110
                    }
111
                }
112
            }
113
114
            return (0 == count($args) + count($args_numeric) + count($args_string)) ? null : true;
115
        }
116
117
        /**
118
         * Function to parse class prefix
119
         *
120
         * @var string $class_string string to be parsed
121
         * @var mixed  $pattern
122
         * @var mixed  $replacement
123
         *
124
         * @return bool true on success
125
         */
126 View Code Duplication
        public static function planetParseClass($class_string, $pattern = '', $replacement = '')
127
        {
128
            if (empty($class_string)) {
129
                return;
130
            }
131
            $patterns     = ["/\[CLASS_PREFIX\]/"];
132
            $replacements = [ucfirst(strtolower($GLOBALS['moddirname']))];
133
            if (!empty($pattern) && !is_array($pattern) && !is_array($replacement)) {
134
                $pattern     = [$pattern];
135
                $replacement = [$replacement];
136
            }
137
            if (is_array($pattern) && count($pattern) > 0) {
138
                $ii = 0;
139
                foreach ($pattern as $pat) {
140
                    if (!in_array($pat, $patterns)) {
141
                        $patterns[]     = $pat;
142
                        $replacements[] = isset($replacement[$ii]) ? $replacement[$ii] : '';
143
                    }
144
                    ++$ii;
145
                }
146
            }
147
            $class_string = preg_replace($patterns, $replacements, $class_string);
148
            eval($class_string);
149
150
            return true;
151
        }
152
153
        /**
154
         * Function to parse function prefix
155
         *
156
         * @var string $function_string string to be parsed
157
         * @var mixed  $pattern
158
         * @var mixed  $replacement
159
         *
160
         * @return bool true on success
161
         */
162 View Code Duplication
        public static function planetParseFunction($function_string, $pattern = '', $replacement = '')
163
        {
164
            if (empty($function_string)) {
165
                return;
166
            }
167
            $patterns     = ["/\[DIRNAME\]/", "/\[VAR_PREFIX\]/"];
168
            $replacements = [$GLOBALS['moddirname'], $GLOBALS['VAR_PREFIX']];
169
            if (!empty($pattern) && !is_array($pattern) && !is_array($replacement)) {
170
                $pattern     = [$pattern];
171
                $replacement = [$replacement];
172
            }
173
            if (is_array($pattern) && count($pattern) > 0) {
174
                $ii = 0;
175
                foreach ($pattern as $pat) {
176
                    if (!in_array($pat, $patterns)) {
177
                        $patterns[]     = $pat;
178
                        $replacements[] = isset($replacement[$ii]) ? $replacement[$ii] : '';
179
                    }
180
                    ++$ii;
181
                }
182
            }
183
            $function_string = preg_replace($patterns, $replacements, $function_string);
184
            if (is_array($function_string)) {
185
                eval($function_string);
186
            }
187
188
            return true;
189
        }
190
191
        /**
192
         * Function to convert UNIX time to formatted time string
193
         * @param        $time
194
         * @param string $format
195
         * @return string
196
         */
197
        public static function planetFormatTimestamp($time, $format = '')
198
        {
199
            if (empty($time)) {
200
                return '';
201
            }
202
203
            return formatTimestamp($time, $format);
204
        }
205
206
        /**
207
         * Function to a list of user names associated with their user IDs
208
         * @param int  $userid
209
         * @param int  $usereal
210
         * @param bool $linked
211
         * @return array
212
         */
213 View Code Duplication
        public static function &planetGetUnameFromId($userid, $usereal = 0, $linked = false)
214
        {
215
            if (!is_array($userid)) {
216
                $userid = [$userid];
217
            }
218
            $users =& mod_getUnameFromIds($userid, $usereal, $linked);
219
220
            return $users;
221
        }
222
223
        /**
224
         * Function to parse links, links are delimited by link break, URL and title of a link are delimited by space
225
         *
226
         * @var string $text raw content
227
         *
228
         * @return array associative array of link url and title
229
         */
230 View Code Duplication
        public static function &planetParseLinks($text)
231
        {
232
            $myts       = \MyTextSanitizer::getInstance();
233
            $link_array = preg_split("/(\r\n|\r|\n)( *)/", $text);
234
            $links      = [];
235
            if (count($link_array) > 0) {
236
                foreach ($link_array as $link) {
237
                    @list($url, $title) = array_map('trim', preg_split('/ /', $link, 2));
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
238
                    if (empty($url)) {
239
                        continue;
240
                    }
241
                    //if(empty($title)) $title = $url;
242
                    $links[] = ['url' => $url, 'title' => $myts->htmlSpecialChars($title)];
243
                }
244
            }
245
246
            return $links;
247
        }
248
249
        /**
250
         * @param $pagename
251
         * @return string
252
         */
253
        public static function planetGetTemplate($pagename)
254
        {
255
            return $GLOBALS['VAR_PREFIX'] . '_' . $pagename . '.tpl';
256
        }
257
258
        /**
259
         * @param int $currentoption
260
         */
261
        //public static function planet_adminmenu($currentoption = -1)
262
        //{
263
        //    loadModuleAdminMenu($currentoption, '');
264
        //
265
        //    return;
266
        //}
267
268
        /**
269
         * Function to send a trackback
270
         *
271
         * @param $article
272
         * @param $comment
273
         * @return bool
274
         */
275 View Code Duplication
        public static function planetSendTrackback(&$article, &$comment)
276
        {
277
            $blogHandler = xoops_getModuleHandler('blog', $GLOBALS['moddirname']);
278
            $blog_obj    = $blogHandler->get($article->getVar('blog_id'));
279
            if (!$pattern = $blog_obj->getVar('blog_trackback')) {
280
                return false;
281
            }
282
283
            @list($pat, $rep) = array_map('trim', preg_split("#[\s]+#", $pattern));
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
284
            $trackback_url = preg_replace('#' . $pat . '#', $rep, $article_obj->getVar('art_link'));
285
286
            return static::planetTrackback($trackback_url, $article);
287
        }
288
289
        /**
290
         * @param $trackback_url
291
         * @param $article
292
         * @return bool
293
         */
294 View Code Duplication
        public static function planetTrackback($trackback_url, $article)
295
        {
296
            global $myts, $xoopsConfig, $xoopsModule;
297
            /** @var Planet\Helper $helper */
298
            $helper = Planet\Helper::getInstance();
299
300
            $title         = $article->getVar('art_title');
301
            $excerpt       = $article->getVar('art_content');
302
            $blog_name     = $xoopsConfig['sitename'] . '-' . $xoopsModule->getVar('name');
303
            $title         = xoops_utf8_encode($title);
304
            $excerpt       = xoops_utf8_encode($excerpt);
305
            $blog_name     = xoops_utf8_encode($blog_name);
306
            $charset       = 'utf-8';
307
            $title1        = urlencode($title);
308
            $excerpt1      = urlencode($excerpt);
309
            $name1         = urlencode($blog_name);
310
            $url           = urlencode(XOOPS_URL . '/modules/' . $GLOBALS['moddirname'] . '/view.article.php' . URL_DELIMITER . '' . $article->getVar('art_id'));
311
            $query_string  = "title=$title1&url=$url&blog_name=$name1&excerpt=$excerpt1&charset=$charset";
312
            $trackback_url = parse_url($trackback_url);
313
314
            $http_request = 'POST ' . $trackback_url['path'] . ($trackback_url['query'] ? '?' . $trackback_url['query'] : '') . " HTTP/1.0\r\n";
315
            $http_request .= 'Host: ' . $trackback_url['host'] . "\r\n";
316
            $http_request .= 'Content-Type: application/x-www-form-urlencoded; charset=' . $charset . "\r\n";
317
            $http_request .= 'Content-Length: ' . strlen($query_string) . "\r\n";
318
            $http_request .= 'User-Agent: XOOPS Blogs/' . XOOPS_VERSION;
319
            $http_request .= "\r\n\r\n";
320
            $http_request .= $query_string;
321
            if ('' == $trackback_url['port']) {
322
                $trackback_url['port'] = 80;
323
            }
324
            $fs = @fsockopen($trackback_url['host'], $trackback_url['port'], $errno, $errstr, 4);
325
            @fwrite($fs, $http_request);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
326
            if ($helper->getConfig('do_debug')) {
327
                $debug_file = XOOPS_CACHE_PATH . '/' . $GLOBALS['moddirname'] . '_trackback.log';
328
                $fr         = "\n*****\nRequest:\n\n$http_request\n\nResponse:\n\n";
329
                $fr         .= "CHARSET:$charset\n";
330
                $fr         .= "NAME:$blog_name\n";
331
                $fr         .= 'TITLE:' . $title . "\n";
332
                $fr         .= "EXCERPT:$excerpt\n\n";
333
                while (!@feof($fs)) {
334
                    $fr .= @fgets($fs, 4096);
335
                }
336
                $fr .= "\n\n";
337
338
                if ($fp = fopen($debug_file, 'a')) {
339
                    fwrite($fp, $fr);
340
                    fclose($fp);
341
                } else {
342
                }
343
            }
344
            @fclose($fs);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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...
345
346
            return true;
347
        }
348
349
        /**
350
         * Function to ping servers
351
         * @param $server
352
         * @param $id
353
         */
354 View Code Duplication
        public static function planetGetPing($server, $id)
355
        {
356
            if (is_array($server)) {
357
                foreach ($server as $serv) {
358
                    PlanetUtility::planetGetPing($serv, $id);
359
                }
360
            }
361
            require_once XOOPS_ROOT_PATH . '/modules/' . $GLOBALS['moddirname'] . '/class-IXR.php';
362
363
            // using a timeout of 3 seconds should be enough to cover slow servers
364
            $client            = new IXR_Client($server, false);
365
            $client->timeout   = 3;
366
            $client->useragent .= ' -- XOOPS Article/' . XOOPS_VERSION;
367
368
            // when set to true, this outputs debug messages by itself
369
            $client->debug = false;
370
371
            $blogname = xoops_utf8_encode($GLOBALS['xoopsModule']->getVar('name'));
372
            $home     = XOOPS_URL . '/modules/' . $GLOBALS['moddirname'] . '/';
373
            $rss2_url = XOOPS_URL . '/modules/' . $GLOBALS['moddirname'] . '/xml.php' . URL_DELIMITER . 'rss2.0/' . $id;
374
375
            if (!$client->query('weblogUpdates.extendedPing', $blogname, $home, $rss2_url)) { // then try a normal ping
376
                $client->query('weblogUpdates.ping', $blogname, $home);
377
            }
378
        }
379
380
        /**
381
         * Function to respond to a trackback
382
         * @param int    $error
383
         * @param string $error_message
384
         */
385 View Code Duplication
        public static function planetRespondToTrackback($error = 0, $error_message = '')
386
        {
387
            $charset       = 'utf-8';
388
            $error_message = xoops_utf8_encode($error_message);
389
            header('Content-Type: text/xml; charset="' . $charset . '"');
390
            if ($error) {
391
                echo '<?xml version="1.0" encoding="' . $charset . '"?' . ">\n";
392
                echo "<response>\n";
393
                echo "<error>1</error>\n";
394
                echo "<message>$error_message</message>\n";
395
                echo '</response>';
396
                die();
397
            } else {
398
                echo '<?xml version="1.0" encoding="' . $charset . '"?' . ">\n";
399
                echo "<response>\n";
400
                echo "<error>0</error>\n";
401
                echo '</response>';
402
            }
403
        }
404
405
        /**
406
         * Function to set a cookie with module-specified name
407
         *
408
         * using customized serialization method
409
         * @param        $name
410
         * @param string $string
411
         * @param int    $expire
412
         */
413 View Code Duplication
        public static function planetSetCookie($name, $string = '', $expire = 0)
414
        {
415
            if (is_array($string)) {
416
                $value = [];
417
                foreach ($string as $key => $val) {
418
                    $value[] = $key . '|' . $val;
419
                }
420
                $string = implode(',', $value);
421
            }
422
            setcookie($GLOBALS['VAR_PREFIX'] . $name, $string, (int)$expire, '/');
423
        }
424
425
        /**
426
         * @param      $name
427
         * @param bool $isArray
428
         * @return array|null
429
         */
430 View Code Duplication
        public static function planetGetCookie($name, $isArray = false)
431
        {
432
            $value = isset($_COOKIE[$GLOBALS['VAR_PREFIX'] . $name]) ? $_COOKIE[$GLOBALS['VAR_PREFIX'] . $name] : null;
433
            if ($isArray) {
434
                $_value = $value ? explode(',', $value) : [];
435
                $value  = [];
436
                if (count($_value) > 0) {
437
                    foreach ($_value as $string) {
438
                        $key         = substr($string, 0, strpos($string, '|'));
439
                        $val         = substr($string, strpos($string, '|') + 1);
440
                        $value[$key] = $val;
441
                    }
442
                }
443
                unset($_value);
444
            }
445
446
            return $value;
447
        }
448
449
        /**
450
         * Function to filter text
451
         *
452
         * @param $document
453
         * @return string filtered text
454
         */
455
        public static function &planetHtml2text(&$document)
456
        {
457
            $document = strip_tags($document);
458
459
            return $document;
460
        }
461
462
        // Adapted from PMA_getIp() [phpmyadmin project]
463
464
        /**
465
         * @param bool $asString
466
         * @return mixed
467
         */
468
        public static function planetGetIP($asString = false)
469
        {
470
            return mod_getIP($asString);
471
        }
472
473
        /**
474
         * @param $url
475
         * @return bool|mixed|string
476
         */
477
        public static function planetGetRemoteContent($url)
478
        {
479
            if ($data = static::planetFetchSnoopy($url)) {
480
                return $data;
481
            }
482
            if ($data = static::planetFetchCURL($url)) {
483
                return $data;
484
            }
485
            if ($data = static::planetFetchFopen($url)) {
486
                return $data;
487
            }
488
489
            return false;
490
        }
491
492
        /**
493
         * @param $url
494
         * @return string
495
         */
496 View Code Duplication
        public static function planetFetchSnoopy($url)
497
        {
498
            require_once XOOPS_ROOT_PATH . '/class/snoopy.php';
499
            $snoopy = new Snoopy;
500
            $data   = '';
501
            if (@$snoopy->fetch($url)) {
502
                $data = is_array($snoopy->results) ? implode("\n", $snoopy->results) : $snoopy->results;
503
            }
504
505
            return $data;
506
        }
507
508
        /**
509
         * @param $url
510
         * @return bool|mixed
511
         */
512 View Code Duplication
        public static function planetFetchCURL($url)
513
        {
514
            if (!function_exists('curl_init')) {
515
                return false;
516
            }
517
            $ch = curl_init();    // initialize curl handle
518
            curl_setopt($ch, CURLOPT_URL, $url); // set url to post to
519
            curl_setopt($ch, CURLOPT_FAILONERROR, 1);
520
            curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);// allow redirects
521
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // return into a variable
522
            curl_setopt($ch, CURLOPT_TIMEOUT, 30); // times out after 31s
523
            $data = curl_exec($ch); // run the whole process
524
            curl_close($ch);
525
526
            return $data;
527
        }
528
529
        /**
530
         * @param $url
531
         * @return bool|string
532
         */
533 View Code Duplication
        public static function planetFetchFopen($url)
534
        {
535
            if (!$fp = @fopen($url, 'r')) {
536
                return false;
537
            }
538
            $data = '';
539
            while (!feof($fp)) {
540
                $data .= fgets($fp, 1024);
541
            }
542
            fclose($fp);
543
544
            return $data;
545
        }
546
547
        /**
548
         * @param     $haystack
549
         * @param     $needle
550
         * @param int $offset
551
         * @return bool|int
552
         */
553 View Code Duplication
        public static function planetStrrPos($haystack, $needle, $offset = 0)
554
        {
555
            if (5 == substr(PHP_VERSION, 0, 1)) {
556
                return strrpos($haystack, $needle, $offset);
557
            }
558
            $index = strpos(strrev($haystack), strrev($needle));
559
            if (false === $index) {
560
                return false;
561
            }
562
            $index = strlen($haystack) - strlen($needle) - $index;
563
564
            return $index;
565
        }
566
    }
567
568
endif;
569