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.

include/functions.php (1 issue)

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

This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name.

The variable may have been renamed without also renaming all references.

Loading history...
275
276
        return planetTrackback($trackback_url, $article);
277
    }
278
279
    /**
280
     * @param $trackback_url
281
     * @param $article
282
     * @return bool
283
     */
284 View Code Duplication
    function planetTrackback($trackback_url, $article)
285
    {
286
        global $myts, $xoopsConfig, $xoopsModule;
287
        /** @var Planet\Helper $helper */
288
        $helper = Planet\Helper::getInstance();
289
290
        $title         = $article->getVar('art_title');
291
        $excerpt       = $article->getVar('art_content');
292
        $blog_name     = $xoopsConfig['sitename'] . '-' . $xoopsModule->getVar('name');
293
        $title         = xoops_utf8_encode($title);
294
        $excerpt       = xoops_utf8_encode($excerpt);
295
        $blog_name     = xoops_utf8_encode($blog_name);
296
        $charset       = 'utf-8';
297
        $title1        = urlencode($title);
298
        $excerpt1      = urlencode($excerpt);
299
        $name1         = urlencode($blog_name);
300
        $url           = urlencode(XOOPS_URL . '/modules/' . $GLOBALS['moddirname'] . '/view.article.php' . URL_DELIMITER . '' . $article->getVar('art_id'));
301
        $query_string  = "title=$title1&url=$url&blog_name=$name1&excerpt=$excerpt1&charset=$charset";
302
        $trackback_url = parse_url($trackback_url);
303
304
        $http_request = 'POST ' . $trackback_url['path'] . ($trackback_url['query'] ? '?' . $trackback_url['query'] : '') . " HTTP/1.0\r\n";
305
        $http_request .= 'Host: ' . $trackback_url['host'] . "\r\n";
306
        $http_request .= 'Content-Type: application/x-www-form-urlencoded; charset=' . $charset . "\r\n";
307
        $http_request .= 'Content-Length: ' . strlen($query_string) . "\r\n";
308
        $http_request .= 'User-Agent: XOOPS Blogs/' . XOOPS_VERSION;
309
        $http_request .= "\r\n\r\n";
310
        $http_request .= $query_string;
311
        if ('' == $trackback_url['port']) {
312
            $trackback_url['port'] = 80;
313
        }
314
        $fs = @fsockopen($trackback_url['host'], $trackback_url['port'], $errno, $errstr, 4);
315
        @fwrite($fs, $http_request);
316
        if ($helper->getConfig('do_debug')) {
317
            $debug_file = XOOPS_CACHE_PATH . '/' . $GLOBALS['moddirname'] . '_trackback.log';
318
            $fr         = "\n*****\nRequest:\n\n$http_request\n\nResponse:\n\n";
319
            $fr         .= "CHARSET:$charset\n";
320
            $fr         .= "NAME:$blog_name\n";
321
            $fr         .= 'TITLE:' . $title . "\n";
322
            $fr         .= "EXCERPT:$excerpt\n\n";
323
            while (!@feof($fs)) {
324
                $fr .= @fgets($fs, 4096);
325
            }
326
            $fr .= "\n\n";
327
328
            if ($fp = fopen($debug_file, 'a')) {
329
                fwrite($fp, $fr);
330
                fclose($fp);
331
            } else {
332
            }
333
        }
334
        @fclose($fs);
335
336
        return true;
337
    }
338
339
    /**
340
     * Function to ping servers
341
     * @param $server
342
     * @param $id
343
     */
344 View Code Duplication
    function planetGetPing($server, $id)
345
    {
346
        if (is_array($server)) {
347
            foreach ($server as $serv) {
348
                planetGetPing($serv, $id);
349
            }
350
        }
351
        require_once XOOPS_ROOT_PATH . '/modules/' . $GLOBALS['moddirname'] . '/class-IXR.php';
352
353
        // using a timeout of 3 seconds should be enough to cover slow servers
354
        $client            = new IXR_Client($server, false);
355
        $client->timeout   = 3;
356
        $client->useragent .= ' -- XOOPS Article/' . XOOPS_VERSION;
357
358
        // when set to true, this outputs debug messages by itself
359
        $client->debug = false;
360
361
        $blogname = xoops_utf8_encode($GLOBALS['xoopsModule']->getVar('name'));
362
        $home     = XOOPS_URL . '/modules/' . $GLOBALS['moddirname'] . '/';
363
        $rss2_url = XOOPS_URL . '/modules/' . $GLOBALS['moddirname'] . '/xml.php' . URL_DELIMITER . 'rss2.0/' . $id;
364
365
        if (!$client->query('weblogUpdates.extendedPing', $blogname, $home, $rss2_url)) { // then try a normal ping
366
            $client->query('weblogUpdates.ping', $blogname, $home);
367
        }
368
    }
369
370
    /**
371
     * Function to respond to a trackback
372
     * @param int    $error
373
     * @param string $error_message
374
     */
375 View Code Duplication
    function planetRespondToTrackback($error = 0, $error_message = '')
376
    {
377
        $charset       = 'utf-8';
378
        $error_message = xoops_utf8_encode($error_message);
379
        header('Content-Type: text/xml; charset="' . $charset . '"');
380
        if ($error) {
381
            echo '<?xml version="1.0" encoding="' . $charset . '"?' . ">\n";
382
            echo "<response>\n";
383
            echo "<error>1</error>\n";
384
            echo "<message>$error_message</message>\n";
385
            echo '</response>';
386
            die();
387
        } else {
388
            echo '<?xml version="1.0" encoding="' . $charset . '"?' . ">\n";
389
            echo "<response>\n";
390
            echo "<error>0</error>\n";
391
            echo '</response>';
392
        }
393
    }
394
395
    /**
396
     * Function to set a cookie with module-specified name
397
     *
398
     * using customized serialization method
399
     * @param        $name
400
     * @param string $string
401
     * @param int    $expire
402
     */
403 View Code Duplication
    function planetSetCookie($name, $string = '', $expire = 0)
404
    {
405
        if (is_array($string)) {
406
            $value = [];
407
            foreach ($string as $key => $val) {
408
                $value[] = $key . '|' . $val;
409
            }
410
            $string = implode(',', $value);
411
        }
412
        setcookie($GLOBALS['VAR_PREFIX'] . $name, $string, (int)$expire, '/');
413
    }
414
415
    /**
416
     * @param      $name
417
     * @param bool $isArray
418
     * @return array|null
419
     */
420 View Code Duplication
    function planetGetCookie($name, $isArray = false)
421
    {
422
        $value = isset($_COOKIE[$GLOBALS['VAR_PREFIX'] . $name]) ? $_COOKIE[$GLOBALS['VAR_PREFIX'] . $name] : null;
423
        if ($isArray) {
424
            $_value = $value ? explode(',', $value) : [];
425
            $value  = [];
426
            if (count($_value) > 0) {
427
                foreach ($_value as $string) {
428
                    $key         = substr($string, 0, strpos($string, '|'));
429
                    $val         = substr($string, strpos($string, '|') + 1);
430
                    $value[$key] = $val;
431
                }
432
            }
433
            unset($_value);
434
        }
435
436
        return $value;
437
    }
438
439
    /**
440
     * Function to filter text
441
     *
442
     * @param $document
443
     * @return string filtered text
444
     */
445
    function &planetHtml2text(&$document)
446
    {
447
        $document = strip_tags($document);
448
449
        return $document;
450
    }
451
452
    // Adapted from PMA_getIp() [phpmyadmin project]
453
    /**
454
     * @param bool $asString
455
     * @return mixed
456
     */
457
    function planetGetIP($asString = false)
458
    {
459
        return mod_getIP($asString);
460
    }
461
462
    /**
463
     * @param $url
464
     * @return bool|mixed|string
465
     */
466
    function planetGetRemoteContent($url)
467
    {
468
        if ($data = planet_fetch_snoopy($url)) {
469
            return $data;
470
        }
471
        if ($data = planet_fetch_CURL($url)) {
472
            return $data;
473
        }
474
        if ($data = planet_fetch_fopen($url)) {
475
            return $data;
476
        }
477
478
        return false;
479
    }
480
481
    /**
482
     * @param $url
483
     * @return string
484
     */
485 View Code Duplication
    function planet_fetch_snoopy($url)
486
    {
487
        require_once XOOPS_ROOT_PATH . '/class/snoopy.php';
488
        $snoopy = new Snoopy;
489
        $data   = '';
490
        if (@$snoopy->fetch($url)) {
491
            $data = is_array($snoopy->results) ? implode("\n", $snoopy->results) : $snoopy->results;
492
        }
493
494
        return $data;
495
    }
496
497
    /**
498
     * @param $url
499
     * @return bool|mixed
500
     */
501 View Code Duplication
    function planet_fetch_CURL($url)
502
    {
503
        if (!function_exists('curl_init')) {
504
            return false;
505
        }
506
        $ch = curl_init();    // initialize curl handle
507
        curl_setopt($ch, CURLOPT_URL, $url); // set url to post to
508
        curl_setopt($ch, CURLOPT_FAILONERROR, 1);
509
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);// allow redirects
510
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // return into a variable
511
        curl_setopt($ch, CURLOPT_TIMEOUT, 30); // times out after 31s
512
        $data = curl_exec($ch); // run the whole process
513
        curl_close($ch);
514
515
        return $data;
516
    }
517
518
    /**
519
     * @param $url
520
     * @return bool|string
521
     */
522 View Code Duplication
    function planet_fetch_fopen($url)
523
    {
524
        if (!$fp = @fopen($url, 'r')) {
525
            return false;
526
        }
527
        $data = '';
528
        while (!feof($fp)) {
529
            $data .= fgets($fp, 1024);
530
        }
531
        fclose($fp);
532
533
        return $data;
534
    }
535
536
    /**
537
     * @param     $haystack
538
     * @param     $needle
539
     * @param int $offset
540
     * @return bool|int
541
     */
542 View Code Duplication
    function planetStrrPos($haystack, $needle, $offset = 0)
543
    {
544
        if (5 == substr(PHP_VERSION, 0, 1)) {
545
            return strrpos($haystack, $needle, $offset);
546
        }
547
        $index = strpos(strrev($haystack), strrev($needle));
548
        if (false === $index) {
549
            return false;
550
        }
551
        $index = strlen($haystack) - strlen($needle) - $index;
552
553
        return $index;
554
    }
555
endif;
556