Issues (661)

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/gtickets.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
2
// GIJOE's Ticket Class (based on Marijuana's Oreteki XOOPS)
3
// nobunobu's suggestions are applied
4
5
if (!class_exists('XoopsGTicket')) {
6
    /**
7
     * Class XoopsGTicket
8
     */
9
    class XoopsGTicket
10
    {
11
12
        public $_errors       = array();
13
        public $_latest_token = '';
14
        public $messages      = array();
15
16
        /**
17
         * XoopsGTicket constructor.
18
         */
19
        public function __construct()
20
        {
21
            global $xoopsConfig;
22
23
            // language file
24
            if (defined('XOOPS_ROOT_PATH') && !empty($xoopsConfig['language'])
25
                && !strstr($xoopsConfig['language'], '/')
26
            ) {
27
                if (file_exists(dirname(__DIR__) . '/language/' . $xoopsConfig['language'] . '/gticket_messages.phtml')) {
28
                    include dirname(__DIR__) . '/language/' . $xoopsConfig['language'] . '/gticket_messages.phtml';
29
                }
30
            }
31
32
            // default messages
33
            if (empty($this->messages)) {
34
                $this->messages = array(
35
                    'err_general'       => 'GTicket Error',
36
                    'err_nostubs'       => 'No stubs found',
37
                    'err_noticket'      => 'No ticket found',
38
                    'err_nopair'        => 'No valid ticket-stub pair found',
39
                    'err_timeout'       => 'Time out',
40
                    'err_areaorref'     => 'Invalid area or referer',
41
                    'fmt_prompt4repost' => 'error(s) found:<br><span style="background-color:red;font-weight:bold;color:white;">%s</span><br>Confirm it.<br>And do you want to post again?',
42
                    'btn_repost'        => 'repost'
43
                );
44
            }
45
        }
46
47
        // render form as plain html
48
        /**
49
         * @param string $salt
50
         * @param int    $timeout
51
         * @param string $area
52
         * @return string
53
         */
54
        public function getTicketHtml($salt = '', $timeout = 1800, $area = '')
55
        {
56
            return '<input type="hidden" name="XOOPS_G_TICKET" value="' . $this->issue($salt, $timeout, $area) . '">';
57
        }
58
59
        // returns an object of XoopsFormHidden including theh ticket
60
        /**
61
         * @param string $salt
62
         * @param int    $timeout
63
         * @param string $area
64
         * @return XoopsFormHidden
65
         */
66
        public function getTicketXoopsForm($salt = '', $timeout = 1800, $area = '')
67
        {
68
            return new XoopsFormHidden('XOOPS_G_TICKET', $this->issue($salt, $timeout, $area));
69
        }
70
71
        // add a ticket as Hidden Element into XoopsForm
72
        /**
73
         * @param        $form
74
         * @param string $salt
75
         * @param int    $timeout
76
         * @param string $area
77
         */
78
        public function addTicketXoopsFormElement(&$form, $salt = '', $timeout = 1800, $area = '')
79
        {
80
            $form->addElement(new XoopsFormHidden('XOOPS_G_TICKET', $this->issue($salt, $timeout, $area)));
81
        }
82
83
        // returns an array for xoops_confirm();
84
        /**
85
         * @param string $salt
86
         * @param int    $timeout
87
         * @param string $area
88
         * @return array
89
         */
90
        public function getTicketArray($salt = '', $timeout = 1800, $area = '')
91
        {
92
            return array('XOOPS_G_TICKET' => $this->issue($salt, $timeout, $area));
93
        }
94
95
        // return GET parameter string.
96
        /**
97
         * @param string $salt
98
         * @param bool   $noamp
99
         * @param int    $timeout
100
         * @param string $area
101
         * @return string
102
         */
103
        public function getTicketParamString($salt = '', $noamp = false, $timeout = 1800, $area = '')
104
        {
105
            return ($noamp ? '' : '&amp;') . 'XOOPS_G_TICKET=' . $this->issue($salt, $timeout, $area);
106
        }
107
108
        // issue a ticket
109
        /**
110
         * @param string $salt
111
         * @param int    $timeout
112
         * @param string $area
113
         * @return string
114
         */
115
        public function issue($salt = '', $timeout = 1800, $area = '')
116
        {
117
            global $xoopsModule;
118
119
            if ('' === $salt) {
120
                $salt = '$2y$07$' . str_replace('+', '.', base64_encode(mcrypt_create_iv(16, MCRYPT_DEV_URANDOM)));
121
            }
122
123
            // create a token
124
            list($usec, $sec) = explode(' ', microtime());
125
            $appendix_salt       = empty($_SERVER['PATH']) ? XOOPS_DB_NAME : $_SERVER['PATH'];
126
            $token               = crypt($salt . $usec . $appendix_salt . $sec, $salt);
127
            $this->_latest_token = $token;
128
129
            if (empty($_SESSION['XOOPS_G_STUBS'])) {
130
                $_SESSION['XOOPS_G_STUBS'] = array();
131
            }
132
133
            // limit max stubs 10
134
            if (count($_SESSION['XOOPS_G_STUBS']) > 10) {
135
                $_SESSION['XOOPS_G_STUBS'] = array_slice($_SESSION['XOOPS_G_STUBS'], -10);
136
            }
137
138
            // record referer if browser send it
139
            $referer = empty($_SERVER['HTTP_REFERER']) ? '' : $_SERVER['REQUEST_URI'];
140
141
            // area as module's dirname
142
            if (!$area && is_object(@$xoopsModule)) {
143
                $area = $xoopsModule->getVar('dirname');
144
            }
145
146
            // store stub
147
            $_SESSION['XOOPS_G_STUBS'][] = array(
148
                'expire'  => time() + $timeout,
149
                'referer' => $referer,
150
                'area'    => $area,
151
                'token'   => $token
152
            );
153
154
            // paid md5ed token as a ticket
155
            return md5($token . XOOPS_DB_PREFIX);
156
        }
157
158
        // check a ticket
159
        /**
160
         * @param bool   $post
161
         * @param string $area
162
         * @param bool   $allow_repost
163
         * @return bool
0 ignored issues
show
Should the return type not be null|boolean?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
164
         */
165
        public function check($post = true, $area = '', $allow_repost = true)
166
        {
167
            global $xoopsModule;
168
169
            $this->_errors = array();
170
171
            // CHECK: stubs are not stored in session
172
            if (!is_array(@$_SESSION['XOOPS_G_STUBS'])) {
173
                $this->_errors[]           = $this->messages['err_nostubs'];
174
                $_SESSION['XOOPS_G_STUBS'] = array();
175
            }
176
177
            // get key&val of the ticket from a user's query
178
            $ticket = $post ? @$_POST['XOOPS_G_TICKET'] : @$_GET['XOOPS_G_TICKET'];
179
180
            // CHECK: no tickets found
181
            if (empty($ticket)) {
182
                $this->_errors[] = $this->messages['err_noticket'];
183
            }
184
185
            // gargage collection & find a right stub
186
            $stubs_tmp                 = $_SESSION['XOOPS_G_STUBS'];
187
            $_SESSION['XOOPS_G_STUBS'] = array();
188
            foreach ($stubs_tmp as $stub) {
189
                // default lifetime 30min
190
                if ($stub['expire'] >= time()) {
191
                    if (md5($stub['token'] . XOOPS_DB_PREFIX) === $ticket) {
192
                        $found_stub = $stub;
193
                    } else {
194
                        // store the other valid stubs into session
195
                        $_SESSION['XOOPS_G_STUBS'][] = $stub;
196
                    }
197
                } else {
198
                    if (md5($stub['token'] . XOOPS_DB_PREFIX) === $ticket) {
199
                        // not CSRF but Time-Out
200
                        $timeout_flag = true;
201
                    }
202
                }
203
            }
204
205
            // CHECK: the right stub found or not
206
            if (empty($found_stub)) {
207
                if (empty($timeout_flag)) {
208
                    $this->_errors[] = $this->messages['err_nopair'];
209
                } else {
210
                    $this->_errors[] = $this->messages['err_timeout'];
211
                }
212
            } else {
213
214
                // set area if necessary
215
                // area as module's dirname
216
                if (!$area && is_object(@$xoopsModule)) {
217
                    $area = $xoopsModule->getVar('dirname');
218
                }
219
220
                // check area or referer
221
                if (@$found_stub['area'] == $area) {
222
                    $area_check = true;
223
                }
224
                if (!empty($found_stub['referer']) && strstr(@$_SERVER['HTTP_REFERER'], $found_stub['referer'])) {
225
                    $referer_check = true;
226
                }
227
228
                if (empty($area_check) && empty($referer_check)) { // loose
229
                    $this->_errors[] = $this->messages['err_areaorref'];
230
                }
231
            }
232
233
            if (!empty($this->_errors)) {
234
                if ($allow_repost) {
235
                    // repost form
236
                    $this->draw_repost_form($area);
237
                    exit;
238
                } else {
239
                    // failed
240
                    $this->clear();
241
242
                    return false;
243
                }
244
            } else {
245
                // all green
246
                return true;
247
            }
248
        }
249
250
        // draw form for repost
251
        /**
252
         * @param string $area
253
         */
254
        public function draw_repost_form($area = '')
255
        {
256
            // Notify which file is broken
257
            if (headers_sent()) {
258
                restore_errorHandler();
259
                set_errorHandler('GTicket_ErrorHandler4FindOutput');
260
                header('Dummy: for warning');
261
                restore_errorHandler();
262
                exit;
263
            }
264
265
            error_reporting(0);
266
            while (ob_get_level()) {
267
                ob_end_clean();
268
            }
269
270
            $table = '<table>';
271
            $form  = '<form action="?' . htmlspecialchars(@$_SERVER['QUERY_STRING'], ENT_QUOTES) . '" method="post" >';
272
            foreach ($_POST as $key => $val) {
273
                if ($key == 'XOOPS_G_TICKET') {
274
                    continue;
275
                }
276
                if (get_magic_quotes_gpc()) {
277
                    $key = stripslashes($key);
278
                }
279
                if (is_array($val)) {
280
                    list($tmp_table, $tmp_form) = $this->extract_post_recursive(htmlspecialchars($key, ENT_QUOTES), $val);
281
                    $table .= $tmp_table;
282
                    $form .= $tmp_form;
283
                } else {
284
                    if (get_magic_quotes_gpc()) {
285
                        $val = stripslashes($val);
286
                    }
287
                    $table .= '<tr><th>' . htmlspecialchars($key, ENT_QUOTES) . '</th><td>' . htmlspecialchars($val, ENT_QUOTES) . '</td></tr>' . "\n";
288
                    $form .= '<input type="hidden" name="' . htmlspecialchars($key, ENT_QUOTES) . '" value="' . htmlspecialchars($val, ENT_QUOTES) . '">' . "\n";
289
                }
290
            }
291
            $table .= '</table>';
292
            $form .= $this->getTicketHtml(__LINE__, 300, $area) . '<input type="submit" value="' . $this->messages['btn_repost'] . '"></form>';
293
294
            echo '<html><head><title>' . $this->messages['err_general'] . '</title><style>table,td,th {border:solid black 1px; border-collapse:collapse;}</style></head><body>' . sprintf($this->messages['fmt_prompt4repost'], $this->getErrors()) . $table . $form . '</body></html>';
295
        }
296
297
        /**
298
         * @param $key_name
299
         * @param $tmp_array
300
         * @return array
301
         */
302
        public function extract_post_recursive($key_name, $tmp_array)
303
        {
304
            $table = '';
305
            $form  = '';
306
            foreach ($tmp_array as $key => $val) {
307
                if (get_magic_quotes_gpc()) {
308
                    $key = stripslashes($key);
309
                }
310
                if (is_array($val)) {
311
                    list($tmp_table, $tmp_form) = $this->extract_post_recursive($key_name . '[' . htmlspecialchars($key, ENT_QUOTES) . ']', $val);
312
                    $table .= $tmp_table;
313
                    $form .= $tmp_form;
314
                } else {
315
                    if (get_magic_quotes_gpc()) {
316
                        $val = stripslashes($val);
317
                    }
318
                    $table .= '<tr><th>' . $key_name . '[' . htmlspecialchars($key, ENT_QUOTES) . ']</th><td>' . htmlspecialchars($val, ENT_QUOTES) . '</td></tr>' . "\n";
319
                    $form .= '<input type="hidden" name="' . $key_name . '[' . htmlspecialchars($key, ENT_QUOTES) . ']" value="' . htmlspecialchars($val, ENT_QUOTES) . '">' . "\n";
320
                }
321
            }
322
323
            return array($table, $form);
324
        }
325
326
        // clear all stubs
327
        public function clear()
328
        {
329
            $_SESSION['XOOPS_G_STUBS'] = array();
330
        }
331
332
        // Ticket Using
333
        /**
334
         * @return bool
335
         */
336
        public function using()
337
        {
338
            if (!empty($_SESSION['XOOPS_G_STUBS'])) {
339
                return true;
340
            } else {
341
                return false;
342
            }
343
        }
344
345
        // return errors
346
        /**
347
         * @param bool $ashtml
348
         * @return array|string
349
         */
350
        public function getErrors($ashtml = true)
351
        {
352
            if ($ashtml) {
353
                $ret = '';
354
                foreach ($this->_errors as $msg) {
355
                    $ret .= "{$msg}<br>\n";
356
                }
357
            } else {
358
                $ret = $this->_errors;
359
            }
360
361
            return $ret;
362
        }
363
364
        // end of class
365
    }
366
367
    // create a instance in global scope
368
    $GLOBALS['xoopsGTicket'] = new XoopsGTicket();
369
}
370
371
if (!function_exists('admin_refcheck')) {
372
373
    //Admin Referer Check By Marijuana(Rev.011)
374
    /**
375
     * @param string $chkref
376
     * @return bool
377
     */
378
    function admin_refcheck($chkref = '')
379
    {
380
        if (empty($_SERVER['HTTP_REFERER'])) {
381
            return true;
382
        } else {
383
            $ref = $_SERVER['HTTP_REFERER'];
384
        }
385
        $cr = XOOPS_URL;
386
        if ($chkref != '') {
387
            $cr .= $chkref;
388
        }
389
        if (strpos($ref, $cr) !== 0) {
390
            return false;
391
        }
392
393
        return true;
394
    }
395
}
396
397
/**
398
 * @param $errNo
399
 * @param $errStr
400
 * @param $errFile
401
 * @param $errLine
402
 */
403
function GTicket_ErrorHandler4FindOutput($errNo, $errStr, $errFile, $errLine)
0 ignored issues
show
The parameter $errNo is not used and could be removed.

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

Loading history...
The parameter $errFile is not used and could be removed.

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

Loading history...
The parameter $errLine is not used and could be removed.

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

Loading history...
404
{
405
    if (preg_match('?' . preg_quote(XOOPS_ROOT_PATH) . '([^:]+)\:(\d+)?', $errStr, $regs)) {
406
        echo 'Irregular output! check the file ' . htmlspecialchars($regs[1]) . ' line ' . htmlspecialchars($regs[2]);
407
    } else {
408
        echo 'Irregular output! check language files etc.';
409
    }
410
411
    return;
412
}
413