x Sorry, these patches are not available anymore due to data migration. Please run a fresh inspection.

Issues (130)

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.

player_stats.php (2 issues)

Labels
Severity
1
<?php
2
3
// $Id$
4
//  ------------------------------------------------------------------------ //
5
//                XOOPS - PHP Content Management System                      //
6
//                    Copyright (c) 2000 XOOPS.org                           //
7
//                       <https://xoops.org>                             //
8
// ------------------------------------------------------------------------- //
9
//  This program is free software; you can redistribute it and/or modify     //
10
//  it under the terms of the GNU General Public License as published by     //
11
//  the Free Software Foundation; either version 2 of the License, or        //
12
//  (at your option) any later version.                                      //
13
//                                                                           //
14
//  You may not change or alter any portion of this comment or credits       //
15
//  of supporting developers from this source code or any supporting         //
16
//  source code which is considered copyrighted (c) material of the          //
17
//  original comment or credit authors.                                      //
18
//                                                                           //
19
//  This program is distributed in the hope that it will be useful,          //
20
//  but WITHOUT ANY WARRANTY; without even the implied warranty of           //
21
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            //
22
//  GNU General Public License for more details.                             //
23
//                                                                           //
24
//  You should have received a copy of the GNU General Public License        //
25
//  along with this program; if not, write to the Free Software              //
26
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA //
27
//  ------------------------------------------------------------------------ //
28
29
/**
30
 * Display an individual chess player's stats.
31
 *
32
 * @package    chess
33
 * @subpackage player_stats
34
 */
35
36
/**#@+
37
 */
38
39
$GLOBALS['xoopsOption']['template_main'] = 'chess_player_stats.tpl';
40
require __DIR__ . '/header.php';
41
42
require_once XOOPS_ROOT_PATH . '/class/xoopsformloader.php';
43
require_once XOOPS_ROOT_PATH . '/class/pagenav.php';
44
require_once XOOPS_ROOT_PATH . '/modules/chess/include/constants.inc.php';
45
require_once XOOPS_ROOT_PATH . '/modules/chess/include/functions.php';
46
require_once XOOPS_ROOT_PATH . '/modules/chess/include/ratings.php';
47
48
$xoopsConfig['module_cache'][$xoopsModule->getVar('mid')] = 0; // disable caching
49
50
// user input
51
$player_uid   = (int)($_POST['player_uid'] ?? @$_GET['player_uid']);
52
$player_uname = trim(@$_POST['player_uname']); // unsanitized
53
$cstart       = (int)@$_GET['cstart']; // for page nav: offset of first row of results (challenges) to display (default to 0)
54
$gstart       = (int)@$_GET['gstart']; // for page nav: offset of first row of results (games) to display (default to 0)
55
$show_option  = (int)($_POST['show_option'] ?? @$_GET['show_option']);
56
57
#var_dump($_REQUEST);#*#DEBUG#
58
59
// If player username provided, map it to a user ID, overriding any provided value of player user ID.
60
if (!empty($player_uname)) {
61
    $player_uid = chess_uname_to_uid($player_uname);
62
    // Otherwise, if player user ID provided, map it to a username.
63
} elseif (0 != $player_uid) {
64
    $memberHandler = xoops_getHandler('member');
65
66
    $player_user = $memberHandler->getUser($player_uid);
0 ignored issues
show
The method getUser() does not exist on XoopsObjectHandler. It seems like you code against a sub-type of XoopsObjectHandler such as XoopsAvatarHandler or XoopsPersistableObjectHandler. ( Ignorable by Annotation )

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

66
    /** @scrutinizer ignore-call */ 
67
    $player_user = $memberHandler->getUser($player_uid);
Loading history...
67
68
    $player_uname = is_object($player_user) ? $player_user->getVar('uname') : '';
69
}
70
71
// Check that both user ID and username are now defined.
72
if (0 == $player_uid || empty($player_uname)) {
73
    redirect_header(XOOPS_URL . '/modules/chess/index.php', _CHESS_REDIRECT_DELAY_FAILURE, _MD_CHESS_PLAYER_NOT_FOUND);
74
}
75
76
// Display stats
77
chess_player_stats($player_uid, $player_uname, $show_option, $cstart, $gstart);
78
79
require_once XOOPS_ROOT_PATH . '/footer.php';
80
/**#@-*/
81
82
/**
83
 * Display stats for player.
84
 *
85
 * @param int    $player_uid   Player's user ID
86
 * @param string $player_uname Player's username
87
 * @param int    $show_option  _CHESS_SHOW_ALL_GAMES, _CHESS_SHOW_EXCEPT_SELFPLAY or _CHESS_SHOW_RATED_ONLY
88
 * @param int    $cstart       Starting offset for challenges page navigator
89
 * @param int    $gstart       Starting offset for games page navigator
90
 */
91
function chess_player_stats($player_uid, $player_uname, $show_option = _CHESS_SHOW_EXCEPT_SELFPLAY, $cstart = 0, $gstart = 0)
92
{
93
    global $xoopsDB, $xoopsTpl;
94
95
    $rating_system = chess_moduleConfig('rating_system');
96
97
    $num_provisional_games = chess_ratings_num_provisional_games();
98
99
    // set show_option to default if appropriate
100
101
    if (!$show_option || ('none' == $rating_system && _CHESS_SHOW_RATED_ONLY == $show_option)) {
102
        $show_option = _CHESS_SHOW_EXCEPT_SELFPLAY;
103
    }
104
105
    // get maximum number of items to display on a page, and constrain it to a reasonable value
106
107
    $max_items_to_display = chess_moduleConfig('max_items');
108
109
    $max_items_to_display = min(max($max_items_to_display, 1), 1000);
110
111
    $challenges_table = $xoopsDB->prefix('chess_challenges');
112
113
    $games_table = $xoopsDB->prefix('chess_games');
114
115
    $ratings_table = $xoopsDB->prefix('chess_ratings');
116
117
    $player = [];
118
119
    $player['uid'] = $player_uid;
120
121
    $player['uname'] = $player_uname;
122
123
    // ---------------------------------------------
124
125
    // form for selecting player and display-options
126
127
    // ---------------------------------------------
128
129
    // security token not needed for this form
130
131
    $form = new XoopsThemeForm(_MD_CHESS_SELECT_PLAYER, 'form1', 'player_stats.php');
132
133
    $form->addElement(new XoopsFormText('', 'player_uname', 25, 50, $player_uname));
134
135
    $form->addElement(new XoopsFormButton('', 'submit_select_player', _MD_CHESS_SUBMIT_BUTTON, 'submit'));
136
137
    $menu_show_option = new XoopsFormSelect('', 'show_option', $show_option, 1, false);
138
139
    $menu_show_option->addOption(_CHESS_SHOW_ALL_GAMES, _MD_CHESS_SHOW_ALL_GAMES);
140
141
    $menu_show_option->addOption(_CHESS_SHOW_EXCEPT_SELFPLAY, _MD_CHESS_SHOW_EXCEPT_SELFPLAY); // default
142
143
    if ('none' != $rating_system) {
144
        $menu_show_option->addOption(_CHESS_SHOW_RATED_ONLY, _MD_CHESS_SHOW_RATED_ONLY);
145
    }
146
147
    $form->addElement($menu_show_option);
148
149
    $form->assign($xoopsTpl);
150
151
    // user IDs that will require mapping to usernames
152
153
    $userids = [];
154
155
    // --------------
156
157
    // player's games
158
159
    // --------------
160
161
    // Two queries are performed, one without a limit clause to count the total number of rows for the page navigator,
162
163
    // and one with a limit clause to get the data for display on the current page.
164
165
    // SQL_CALC_FOUND_ROWS and FOUND_ROWS(), available in MySQL 4.0.0, provide a more efficient way of doing this.
166
167
    $where = "'$player_uid' IN (white_uid, black_uid)";
168
169
    if (_CHESS_SHOW_EXCEPT_SELFPLAY == $show_option) {
170
        $where .= ' AND white_uid != black_uid';
171
    } elseif (_CHESS_SHOW_RATED_ONLY == $show_option) {
172
        $where .= ' AND is_rated = "1" AND white_uid != black_uid';
173
    }
174
175
    $result = $xoopsDB->query("SELECT COUNT(*) FROM $games_table WHERE $where");
176
177
    [$num_items] = $xoopsDB->fetchRow($result);
178
179
    $xoopsDB->freeRecordSet($result);
180
181
    $result = $xoopsDB->query(
182
        "
183
        SELECT   game_id, fen_active_color, white_uid, black_uid, pgn_result, is_rated,
184
            UNIX_TIMESTAMP(GREATEST(create_date,start_date,last_date)) AS last_activity
185
        FROM      $games_table
186
        WHERE     $where
187
        ORDER BY  last_activity DESC
188
        LIMIT     $gstart, $max_items_to_display
189
    "
190
    );
191
192
    $games = [];
193
194
    while (false !== ($row = $xoopsDB->fetchArray($result))) {
195
        $games[] = [
196
            'game_id'          => $row['game_id'],
197
            'white_uid'        => $row['white_uid'],
198
            'black_uid'        => $row['black_uid'],
199
            'fen_active_color' => $row['fen_active_color'],
200
            'pgn_result'       => $row['pgn_result'],
201
            'last_activity'    => $row['last_activity'],
202
            'is_rated'         => $row['is_rated'],
203
        ];
204
205
        // save user IDs that will require mapping to usernames
206
207
        if ($row['white_uid']) {
208
            $userids[$row['white_uid']] = 1;
209
        }
210
211
        if ($row['black_uid']) {
212
            $userids[$row['black_uid']] = 1;
213
        }
214
    }
215
216
    $xoopsDB->freeRecordSet($result);
217
218
    $show_option_urlparam = "&amp;show_option=$show_option";
219
220
    $games_pagenav = new XoopsPageNav($num_items, $max_items_to_display, $gstart, 'gstart', "player_uid=$player_uid$show_option_urlparam");
221
222
    // -------------------
223
224
    // player's challenges
225
226
    // -------------------
227
228
    // Two queries are performed, one without a limit clause to count the total number of rows for the page navigator,
229
230
    // and one with a limit clause to get the data for display on the current page.
231
232
    // SQL_CALC_FOUND_ROWS and FOUND_ROWS(), available in MySQL 4.0.0, provide a more efficient way of doing this.
233
234
    $where = "'$player_uid' IN (player1_uid, player2_uid)";
235
236
    if (_CHESS_SHOW_RATED_ONLY == $show_option) {
237
        $where .= ' AND is_rated = "1"';
238
    }
239
240
    $result = $xoopsDB->query("SELECT COUNT(*) FROM $challenges_table WHERE $where");
241
242
    [$num_items] = $xoopsDB->fetchRow($result);
243
244
    $xoopsDB->freeRecordSet($result);
245
246
    $result = $xoopsDB->query(
247
        "
248
        SELECT   challenge_id, game_type, color_option, player1_uid, player2_uid, UNIX_TIMESTAMP(create_date) AS create_date, is_rated
249
        FROM     $challenges_table
250
        WHERE    $where
251
        ORDER BY create_date DESC
252
        LIMIT    $cstart, $max_items_to_display
253
    "
254
    );
255
256
    $challenges = [];
257
258
    while (false !== ($row = $xoopsDB->fetchArray($result))) {
259
        $challenges[] = [
260
            'challenge_id' => $row['challenge_id'],
261
            'game_type'    => $row['game_type'],
262
            'color_option' => $row['color_option'],
263
            'player1_uid'  => $row['player1_uid'],
264
            'player2_uid'  => $row['player2_uid'],
265
            'create_date'  => $row['create_date'],
266
            'is_rated'     => $row['is_rated'],
267
        ];
268
269
        // save user IDs that will require mapping to usernames
270
271
        if ($row['player1_uid']) {
272
            $userids[$row['player1_uid']] = 1;
273
        }
274
275
        if ($row['player2_uid']) {
276
            $userids[$row['player2_uid']] = 1;
277
        }
278
    }
279
280
    $xoopsDB->freeRecordSet($result);
281
282
    $show_option_urlparam = "&amp;show_option=$show_option";
283
284
    $challenges_pagenav = new XoopsPageNav($num_items, $max_items_to_display, $cstart, 'cstart', "player_uid=$player_uid$show_option_urlparam");
285
286
    // ---------
287
288
    // usernames
289
290
    // ---------
291
292
    // get mapping of user IDs to usernames
293
294
    $memberHandler = xoops_getHandler('member');
295
296
    $criteria = new \Criteria('uid', '(' . implode(',', array_keys($userids)) . ')', 'IN');
297
298
    $usernames = $memberHandler->getUserList($criteria);
0 ignored issues
show
The method getUserList() does not exist on XoopsObjectHandler. It seems like you code against a sub-type of XoopsObjectHandler such as XoopsPersistableObjectHandler. ( Ignorable by Annotation )

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

298
    /** @scrutinizer ignore-call */ 
299
    $usernames = $memberHandler->getUserList($criteria);
Loading history...
299
300
    // add usernames to $games
301
302
    foreach ($games as $k => $game) {
303
        $games[$k]['white_uname'] = $usernames[$game['white_uid']] ?? '?';
304
305
        $games[$k]['black_uname'] = $usernames[$game['black_uid']] ?? '?';
306
    }
307
308
    // add usernames to $challenges
309
310
    foreach ($challenges as $k => $challenge) {
311
        $challenges[$k]['player1_uname'] = $usernames[$challenge['player1_uid']] ?? '?';
312
313
        $challenges[$k]['player2_uname'] = $usernames[$challenge['player2_uid']] ?? '?';
314
    }
315
316
    // ---------------------------------------------------
317
318
    // player's rating info (if rating feature is enabled)
319
320
    // ---------------------------------------------------
321
322
    if ('none' != $rating_system) {
323
        $result = $xoopsDB->query(
324
            "
325
            SELECT   player_uid, rating, games_won, games_lost, games_drawn, (games_won+games_lost+games_drawn) AS games_played
326
            FROM     $ratings_table
327
            ORDER BY rating DESC, player_uid ASC
328
        "
329
        );
330
331
        $ranking = 0;
332
333
        while (false !== ($row = $xoopsDB->fetchArray($result))) {
334
            if ($row['games_played'] >= $num_provisional_games) {
335
                ++$ranking;
336
            }
337
338
            if ($row['player_uid'] == $player_uid) {
339
                break;
340
            }
341
        }
342
343
        $xoopsDB->freeRecordSet($result);
344
345
        if ($row['player_uid'] == $player_uid) {
346
            $player['ranking'] = $ranking;
347
348
            $player['rating'] = $row['rating'];
349
350
            $player['games_won'] = $row['games_won'];
351
352
            $player['games_lost'] = $row['games_lost'];
353
354
            $player['games_drawn'] = $row['games_drawn'];
355
356
            $player['games_played'] = $row['games_played'];
357
        }
358
    }
359
360
    // Template variables
361
362
    $player['games'] = $games;
363
364
    $player['challenges'] = $challenges;
365
366
    $xoopsTpl->assign('chess_player', $player);
367
368
    $xoopsTpl->assign('chess_rating_system', chess_moduleConfig('rating_system'));
369
370
    $xoopsTpl->assign('chess_provisional_games', $num_provisional_games);
371
372
    $xoopsTpl->assign('chess_show_option_urlparam', $show_option_urlparam);
373
374
    $xoopsTpl->assign('chess_games_pagenav', $games_pagenav->renderNav());
375
376
    $xoopsTpl->assign('chess_challenges_pagenav', $challenges_pagenav->renderNav());
377
}
378