Issues (388)

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.

admin/songs.php (7 issues)

1
<?php declare(strict_types=1);
2
3
use Xmf\Module\Admin;
4
use Xmf\Request;
5
use XoopsModules\Songlist\Helper;
6
use XoopsModules\Songlist\Uploader;
7
use XoopsModules\Songlist\SongsHandler;
8
use XoopsModules\Songlist\Form\FormController;
9
10
11
require __DIR__ . '/header.php';
12
13
xoops_loadLanguage('admin', 'songlist');
14
15
xoops_cp_header();
16
17
$op     = $_REQUEST['op'] ?? 'songs';
18
$fct    = $_REQUEST['fct'] ?? 'list';
19
$limit  = Request::getInt('limit', 30, 'REQUEST');
20
$start  = Request::getInt('start', 0, 'REQUEST');
21
$order  = !empty($_REQUEST['order']) ? $_REQUEST['order'] : 'DESC';
22
$sort   = !empty($_REQUEST['sort']) ? '' . $_REQUEST['sort'] . '' : 'created';
23
$filter = !empty($_REQUEST['filter']) ? '' . $_REQUEST['filter'] . '' : '1,1';
24
25
switch ($op) {
26
    default:
27
    case 'songs':
28
        switch ($fct) {
29
            default:
30
            case 'list':
31
                $adminObject = Admin::getInstance();
32
                $adminObject->displayNavigation(basename(__FILE__));
33
34
            /** @var SongsHandler $songsHandler */
35
                $songsHandler = Helper::getInstance()->getHandler('Songs');
36
37
                $criteria        = $songsHandler->getFilterCriteria($GLOBALS['filter']);
38
                $ttl             = $songsHandler->getCount($criteria);
39
                $GLOBALS['sort'] = !empty($_REQUEST['sort']) ? '' . $_REQUEST['sort'] . '' : 'created';
40
41
                $pagenav = new \XoopsPageNav($ttl, $GLOBALS['limit'], $GLOBALS['start'], 'start', 'limit=' . $GLOBALS['limit'] . '&sort=' . $GLOBALS['sort'] . '&order=' . $GLOBALS['order'] . '&op=' . $GLOBALS['op'] . '&fct=' . $GLOBALS['fct'] . '&filter=' . $GLOBALS['filter']);
42
                $GLOBALS['xoopsTpl']->assign('pagenav', $pagenav->renderNav());
43
44
                foreach ($songsHandler->filterFields() as $id => $key) {
45
                    $GLOBALS['xoopsTpl']->assign(
46
                        \mb_strtolower(str_replace('-', '_', $key) . '_th'),
47
                        '<a href="'
48
                        . $_SERVER['SCRIPT_NAME']
49
                        . '?start='
50
                        . $GLOBALS['start']
51
                        . '&limit='
52
                        . $GLOBALS['limit']
53
                        . '&sort='
54
                        . $key
55
                        . '&order='
56
                        . (($key == $GLOBALS['sort']) ? ('DESC' === $GLOBALS['order'] ? 'ASC' : 'DESC') : $GLOBALS['order'])
57
                        . '&op='
58
                        . $GLOBALS['op']
59
                        . '&filter='
60
                        . $GLOBALS['filter']
61
                        . '">'
62
                        . (defined('_AM_SONGLIST_TH_' . \mb_strtoupper(str_replace('-', '_', $key))) ? constant('_AM_SONGLIST_TH_' . \mb_strtoupper(str_replace('-', '_', $key))) : '_AM_SONGLIST_TH_' . \mb_strtoupper(str_replace('-', '_', $key)))
63
                        . '</a>'
64
                    );
65
                    $GLOBALS['xoopsTpl']->assign('filter_' . \mb_strtolower(str_replace('-', '_', $key)) . '_th', $songsHandler->getFilterForm($GLOBALS['filter'], $key, $GLOBALS['sort'], $GLOBALS['op'], $GLOBALS['fct']));
66
                }
67
68
                $GLOBALS['xoopsTpl']->assign('limit', $GLOBALS['limit']);
69
                $GLOBALS['xoopsTpl']->assign('start', $GLOBALS['start']);
70
                $GLOBALS['xoopsTpl']->assign('order', $GLOBALS['order']);
71
                $GLOBALS['xoopsTpl']->assign('sort', $GLOBALS['sort']);
72
                $GLOBALS['xoopsTpl']->assign('filter', $GLOBALS['filter']);
73
                $GLOBALS['xoopsTpl']->assign('xoConfig', $GLOBALS['songlistModuleConfig']);
74
75
                $criteria->setStart($GLOBALS['start']);
76
                $criteria->setLimit($GLOBALS['limit']);
77
                $criteria->setSort('`' . $GLOBALS['sort'] . '`');
78
                $criteria->setOrder($GLOBALS['order']);
79
80
                $songss = $songsHandler->getObjects($criteria, true);
81
                foreach ($songss as $cid => $songs) {
82
                    if (is_object($songs)) {
83
                        $GLOBALS['xoopsTpl']->append('songs', $songs->toArray());
84
                    }
85
                }
86
                $GLOBALS['xoopsTpl']->assign('form', FormController::getFormSongs(false));
87
                $GLOBALS['xoopsTpl']->assign('php_self', $_SERVER['SCRIPT_NAME']);
88
                $GLOBALS['xoopsTpl']->display('db:songlist_cpanel_songs_list.tpl');
89
                break;
90
            case 'new':
91
            case 'edit':
92
                $adminObject = Admin::getInstance();
93
                $adminObject->displayNavigation(basename(__FILE__));
94
95
                require_once $GLOBALS['xoops']->path('/class/pagenav.php');
96
97
                $songsHandler = Helper::getInstance()->getHandler('Songs');
98
                if (Request::hasVar('id', 'REQUEST')) {
99
                    $songs = $songsHandler->get(Request::getInt('id', 0, 'REQUEST'));
100
                } else {
101
                    $songs = $songsHandler->create();
102
                }
103
104
                $GLOBALS['xoopsTpl']->assign('form', $songs->getForm());
0 ignored issues
show
The method getForm() does not exist on XoopsObject. It seems like you code against a sub-type of XoopsObject such as XoopsModules\Songlist\Votes or XoopsModules\Songlist\Genre or XoopsModules\Songlist\Voice or SystemSmilies or SystemBanner or XoopsModules\Songlist\Requests or SystemBannerclient or XoopsModules\Songlist\Category or XoopsModules\Songlist\Utf8map or XoopsModules\Songlist\Songs or ProfileCategory or SystemUserrank or XoopsModules\Songlist\Albums or Utf8map or XoopsModules\Songlist\Artists or SystemGroup or SystemBlock or SystemAvatar or SystemUsers. ( Ignorable by Annotation )

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

104
                $GLOBALS['xoopsTpl']->assign('form', $songs->/** @scrutinizer ignore-call */ getForm());
Loading history...
105
                $GLOBALS['xoopsTpl']->assign('php_self', $_SERVER['SCRIPT_NAME']);
106
                $GLOBALS['xoopsTpl']->display('db:songlist_cpanel_songs_edit.tpl');
107
                break;
108
            case 'save':
109
                $songsHandler  = Helper::getInstance()->getHandler('Songs');
110
                $extrasHandler = Helper::getInstance()->getHandler('Extras');
111
                $id            = 0;
112
                $id            = Request::getInt('id', 0, 'REQUEST');
113
                if ($id) {
114
                    $songs = $songsHandler->get($id);
115
                } else {
116
                    $songs = $songsHandler->create();
117
                }
118
                $songs->setVars($_POST[$id]);
119
120
                if (Request::hasVar('mp3' . $id, 'FILES') && !empty($_FILES['mp3' . $id]['title'])) {
121
//                    if (!is_dir($GLOBALS['xoops']->path($GLOBALS['songlistModuleConfig']['upload_areas']))) {
122
//                        foreach (explode('\\', $GLOBALS['xoops']->path($GLOBALS['songlistModuleConfig']['upload_areas'])) as $folders) {
123
//                            foreach (explode('/', $folders) as $folder) {
124
//                                $path .= DS . $folder;
125
//                                if (!mkdir($path, 0777) && !is_dir($path)) {
126
//                                    throw new \RuntimeException(sprintf('Directory "%s" was not created', $path));
127
//                                }
128
//                            }
129
//                        }
130
//                    }
131
132
//                    require_once $GLOBALS['xoops']->path('modules/songlist/include/uploader.php');
133
                    $uploader = new Uploader(
134
                        $GLOBALS['xoops']->path($GLOBALS['songlistModuleConfig']['upload_areas']),
135
                        explode('|', $GLOBALS['songlistModuleConfig']['mp3_mimetype']),
136
                        $GLOBALS['songlistModuleConfig']['mp3_filesize'],
137
                        0,
138
                        0,
139
                        explode('|', $GLOBALS['songlistModuleConfig']['mp3_extensions'])
140
                    );
141
                    try {
142
                        $uploader->setPrefix(mb_substr(md5((string)microtime(true)), random_int(0, 20), 13));
143
                    } catch (Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
144
                    }
145
146
                    if ($uploader->fetchMedia('mp3' . $id)) {
147
                        if (!$uploader->upload()) {
148
                            $adminObject = Admin::getInstance();
149
                            $adminObject->displayNavigation(basename(__FILE__));
150
                            echo $uploader->getErrors();
151
                            xoops_cp_footer();
152
                            exit(0);
153
                        }
154
                        if (mb_strlen($songs->getVar('mp3'))) {
155
                            unlink($GLOBALS['xoops']->path($songs->getVar('path')) . basename($songs->getVar('mp3')));
156
                        }
157
158
                        $songs->setVar('mp3', XOOPS_URL . '/' . str_replace(DS, '/', $GLOBALS['songlistModuleConfig']['upload_areas']) . $uploader->getSavedFileName());
159
                    } else {
160
                        $adminObject = Admin::getInstance();
161
                        $adminObject->displayNavigation(basename(__FILE__));
162
                        echo $uploader->getErrors();
163
                        xoops_cp_footer();
164
                        exit(0);
165
                    }
166
                }
167
                if (!$id = $songsHandler->insert($songs)) {
168
                    redirect_header($_SERVER['SCRIPT_NAME'] . '?op=' . $GLOBALS['op'] . '&fct=list&limit=' . $GLOBALS['limit'] . '&start=' . $GLOBALS['start'] . '&order=' . $GLOBALS['order'] . '&sort=' . $GLOBALS['sort'] . '&filter=' . $GLOBALS['filter'], 10, _AM_SONGLIST_MSG_SONGS_FAILEDTOSAVE);
169
                    exit(0);
170
                }
171
                $extra = $extrasHandler->get($id);
0 ignored issues
show
It seems like $id can also be of type true; however, parameter $id of XoopsModules\Songlist\ExtrasHandler::get() does only seem to accept null, maybe add an additional type check? ( Ignorable by Annotation )

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

171
                $extra = $extrasHandler->get(/** @scrutinizer ignore-type */ $id);
Loading history...
172
                $extra->setVars($_POST[$id]);
173
                $extra->setVar('sid', $id);
174
                $extrasHandler->insert($extra);
175
176
                if ($GLOBALS['songlistModuleConfig']['tags'] && file_exists(XOOPS_ROOT_PATH . '/modules/tag/class/tag.php')) {
177
                    $tagHandler = \XoopsModules\Tag\Helper::getInstance()->getHandler('Tag');
178
                    $tagHandler->updateByItem($_POST['tags'], $id, $GLOBALS['songlistModule']->getVar('dirname'), $songs->getVar('cid'));
0 ignored issues
show
It seems like $id can also be of type true; however, parameter $itemid of XoopsModules\Tag\TagHandler::updateByItem() does only seem to accept integer, maybe add an additional type check? ( Ignorable by Annotation )

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

178
                    $tagHandler->updateByItem($_POST['tags'], /** @scrutinizer ignore-type */ $id, $GLOBALS['songlistModule']->getVar('dirname'), $songs->getVar('cid'));
Loading history...
179
                }
180
181
                if ('new' === isset($_REQUEST['state']) ? $_REQUEST['state'][$_REQUEST['id']]:'') {
0 ignored issues
show
The condition 'new' === IssetNode is always false.
Loading history...
182
                    redirect_header(
183
                        $_SERVER['SCRIPT_NAME'] . '?op=' . $GLOBALS['op'] . '&fct=edit&id=' . $_REQUEST['id'] . '&limit=' . $GLOBALS['limit'] . '&start=' . $GLOBALS['start'] . '&order=' . $GLOBALS['order'] . '&sort=' . $GLOBALS['sort'] . '&filter=' . $GLOBALS['filter'],
184
                        10,
185
                        _AM_SONGLIST_MSG_SONGS_SAVEDOKEY
186
                    );
187
                } else {
188
                    redirect_header($_SERVER['SCRIPT_NAME'] . '?op=' . $GLOBALS['op'] . '&fct=list&limit=' . $GLOBALS['limit'] . '&start=' . $GLOBALS['start'] . '&order=' . $GLOBALS['order'] . '&sort=' . $GLOBALS['sort'] . '&filter=' . $GLOBALS['filter'], 10, _AM_SONGLIST_MSG_SONGS_SAVEDOKEY);
189
                }
190
                exit(0);
191
192
                break;
193
            case 'savelist':
194
                print_r($_FILES);
195
                exit;
196
                $songsHandler = Helper::getInstance()->getHandler('Songs');
197
                foreach ($_REQUEST['id'] as $id) {
198
                    $songs = $songsHandler->get($id);
199
                    $songs->setVars($_POST[$id]);
200
                    if (Request::hasVar('mp3' . $id, 'FILES') && !empty($_FILES['mp3' . $id]['title'])) {
201
//                        if (!is_dir($GLOBALS['xoops']->path($GLOBALS['songlistModuleConfig']['upload_areas']))) {
202
//                            foreach (explode('\\', $GLOBALS['xoops']->path($GLOBALS['songlistModuleConfig']['upload_areas'])) as $folders) {
203
//                                foreach (explode('/', $folders) as $folder) {
204
//                                    $path .= DS . $folder;
205
//                                    if (!mkdir($path, 0777) && !is_dir($path)) {
206
//                                        throw new \RuntimeException(sprintf('Directory "%s" was not created', $path));
207
//                                    }
208
//                                }
209
//                            }
210
//                        }
211
212
//                        require_once $GLOBALS['xoops']->path('modules/songlist/include/uploader.php');
213
                        $uploader = new Uploader(
214
                            $GLOBALS['xoops']->path($GLOBALS['songlistModuleConfig']['upload_areas']),
215
                            explode('|', $GLOBALS['songlistModuleConfig']['mp3_mimetype']),
216
                            $GLOBALS['songlistModuleConfig']['mp3_filesize'],
217
                            0,
218
                            0,
219
                            explode('|', $GLOBALS['songlistModuleConfig']['mp3_extensions'])
220
                        );
221
                        try {
222
                            $uploader->setPrefix(mb_substr(md5((string)microtime(true)), random_int(0, 20), 13));
223
                        } catch (Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
224
                        }
225
226
                        if ($uploader->fetchMedia('mp3' . $id)) {
227
                            if (!$uploader->upload()) {
228
                                $adminObject = Admin::getInstance();
229
                                $adminObject->displayNavigation(basename(__FILE__));
230
                                echo $uploader->getErrors();
231
                                xoops_cp_footer();
232
                                exit(0);
233
                            }
234
                            if (mb_strlen($songs->getVar('mp3'))) {
235
                                unlink($GLOBALS['xoops']->path($songs->getVar('path')) . basename($songs->getVar('mp3')));
236
                            }
237
238
                            $songs->setVar('mp3', XOOPS_URL . '/' . str_replace(DS, '/', $GLOBALS['songlistModuleConfig']['upload_areas']) . $uploader->getSavedFileName());
239
                        } else {
240
                            $adminObject = Admin::getInstance();
241
                            $adminObject->displayNavigation(basename(__FILE__));
242
                            echo $uploader->getErrors();
243
                            xoops_cp_footer();
244
                            exit(0);
245
                        }
246
                    }
247
                    if (!$songsHandler->insert($songs)) {
248
                        redirect_header(
249
                            $_SERVER['SCRIPT_NAME'] . '?op=' . $GLOBALS['op'] . '&fct=list&limit=' . $GLOBALS['limit'] . '&start=' . $GLOBALS['start'] . '&order=' . $GLOBALS['order'] . '&sort=' . $GLOBALS['sort'] . '&filter=' . $GLOBALS['filter'],
250
                            10,
251
                            _AM_SONGLIST_MSG_SONGS_FAILEDTOSAVE
252
                        );
253
                        exit(0);
254
                    }
255
                }
256
                redirect_header($_SERVER['SCRIPT_NAME'] . '?op=' . $GLOBALS['op'] . '&fct=list&limit=' . $GLOBALS['limit'] . '&start=' . $GLOBALS['start'] . '&order=' . $GLOBALS['order'] . '&sort=' . $GLOBALS['sort'] . '&filter=' . $GLOBALS['filter'], 10, _AM_SONGLIST_MSG_SONGS_SAVEDOKEY);
257
                exit(0);
258
                break;
259
            case 'delete':
260
                $songsHandler = Helper::getInstance()->getHandler('Songs');
261
                $id           = 0;
262
                if (Request::hasVar('id', 'POST') && $id = Request::getInt('id', 0, 'POST')) {
263
                    $songs = $songsHandler->get($id);
264
                    if (!$songsHandler->delete($songs)) {
265
                        redirect_header(
266
                            $_SERVER['SCRIPT_NAME'] . '?op=' . $GLOBALS['op'] . '&fct=list&limit=' . $GLOBALS['limit'] . '&start=' . $GLOBALS['start'] . '&order=' . $GLOBALS['order'] . '&sort=' . $GLOBALS['sort'] . '&filter=' . $GLOBALS['filter'],
267
                            10,
268
                            _AM_SONGLIST_MSG_SONGS_FAILEDTODELETE
269
                        );
270
                        exit(0);
271
                    }
272
                    redirect_header($_SERVER['SCRIPT_NAME'] . '?op=' . $GLOBALS['op'] . '&fct=list&limit=' . $GLOBALS['limit'] . '&start=' . $GLOBALS['start'] . '&order=' . $GLOBALS['order'] . '&sort=' . $GLOBALS['sort'] . '&filter=' . $GLOBALS['filter'], 10, _AM_SONGLIST_MSG_SONGS_DELETED);
273
                    exit(0);
274
                }
275
                $songs = $songsHandler->get(Request::getInt('id', 0, 'REQUEST'));
276
                xoops_confirm(
277
                    ['id' => $_REQUEST['id'], 'op' => $_REQUEST['op'], 'fct' => $_REQUEST['fct'], 'limit' => $_REQUEST['limit'], 'start' => $_REQUEST['start'], 'order' => $_REQUEST['order'], 'sort' => $_REQUEST['sort'], 'filter' => $_REQUEST['filter']],
278
                    $_SERVER['SCRIPT_NAME'],
279
                    sprintf(_AM_SONGLIST_MSG_SONGS_DELETE, $songs->getVar('name'))
0 ignored issues
show
It seems like $songs->getVar('name') can also be of type array and array; however, parameter $values of sprintf() does only seem to accept double|integer|string, maybe add an additional type check? ( Ignorable by Annotation )

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

279
                    sprintf(_AM_SONGLIST_MSG_SONGS_DELETE, /** @scrutinizer ignore-type */ $songs->getVar('name'))
Loading history...
280
                );
281
282
                break;
283
        }
284
        break;
285
}
286
287
xoops_cp_footer();
288