Issues (432)

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/fieldslist.php (4 issues)

Labels
Severity
1
<?php declare(strict_types=1);
2
3
/**
4
 * Extended User Profile
5
 *
6
 * You may not change or alter any portion of this comment or credits
7
 * of supporting developers from this source code or any supporting source code
8
 * which is considered copyrighted (c) material of the original comment or credit authors.
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
 *
13
 * @copyright       (c) 2000-2016 XOOPS Project (www.xoops.org)
14
 * @license             GNU GPL 2 (https://www.gnu.org/licenses/gpl-2.0.html)
15
 * @since               2.3.0
16
 * @author              Jan Pedersen
17
 * @author              Taiwen Jiang <[email protected]>
18
 */
19
20
use XoopsModules\Suico\{
21
    CategoryHandler,
22
    Field,
23
    FieldHandler,
24
    Form\FieldForm
25
};
26
27
require_once __DIR__ . '/admin_header.php';
28
xoops_cp_header();
29
$adminObject->addItemButton(_AM_SUICO_FIELD, 'fieldslist.php?op=new', 'add');
30
$adminObject->displayNavigation(basename(__FILE__));
31
$adminObject->displayButton('left');
32
$op = $_REQUEST['op'] ?? (isset($_REQUEST['id']) ? 'edit' : 'list');
33
/** @var FieldHandler $fieldHandler */
34
$fieldHandler = $helper->getHandler('Field');
35
switch ($op) {
36
    default:
37
    case 'list':
38
        $fields = $fieldHandler->getObjects(null, true, false);
39
        /** @var \XoopsModuleHandler $moduleHandler */
40
        $moduleHandler = xoops_getHandler('module');
41
        $modules       = $moduleHandler->getObjects(null, true);
42
        /** @var CategoryHandler $categoryHandler */
43
        $categoryHandler = $helper->getHandler('Category');
44
        $criteria        = new \CriteriaCompo();
45
        $criteria->setSort('cat_weight');
46
        $cats = $categoryHandler->getObjects($criteria, true);
47
        unset($criteria);
48
        $categories[0] = _AM_SUICO_DEFAULT;
49
        if (count($cats) > 0) {
50
            foreach (array_keys($cats) as $i) {
51
                $categories[$cats[$i]->getVar('cat_id')] = $cats[$i]->getVar('cat_title');
52
            }
53
        }
54
        $GLOBALS['xoopsTpl']->assign('categories', $categories);
55
        unset($categories);
56
        $valuetypes = [
57
            XOBJ_DTYPE_ARRAY   => _AM_SUICO_ARRAY,
58
            XOBJ_DTYPE_EMAIL   => _AM_SUICO_EMAIL,
59
            XOBJ_DTYPE_INT     => _AM_SUICO_INT,
60
            XOBJ_DTYPE_TXTAREA => _AM_SUICO_TXTAREA,
61
            XOBJ_DTYPE_TXTBOX  => _AM_SUICO_TXTBOX,
62
            XOBJ_DTYPE_URL     => _AM_SUICO_URL,
63
            XOBJ_DTYPE_OTHER   => _AM_SUICO_OTHER,
64
            XOBJ_DTYPE_MTIME   => _AM_SUICO_DATE,
65
        ];
66
        $fieldtypes = [
67
            'checkbox'     => _AM_SUICO_CHECKBOX,
68
            'group'        => _AM_SUICO_GROUP,
69
            'group_multi'  => _AM_SUICO_GROUPMULTI,
70
            'language'     => _AM_SUICO_LANGUAGE,
71
            'radio'        => _AM_SUICO_RADIO,
72
            'select'       => _AM_SUICO_SELECT,
73
            'select_multi' => _AM_SUICO_SELECTMULTI,
74
            'textarea'     => _AM_SUICO_TEXTAREA,
75
            'dhtml'        => _AM_SUICO_DHTMLTEXTAREA,
76
            'textbox'      => _AM_SUICO_TEXTBOX,
77
            'timezone'     => _AM_SUICO_TIMEZONE,
78
            'yesno'        => _AM_SUICO_YESNO,
79
            'date'         => _AM_SUICO_DATE,
80
            'datetime'     => _AM_SUICO_DATETIME,
81
            'longdate'     => _AM_SUICO_LONGDATE,
82
            'theme'        => _AM_SUICO_THEME,
83
            'autotext'     => _AM_SUICO_AUTOTEXT,
84
            'rank'         => _AM_SUICO_RANK,
85
        ];
86
        foreach (array_keys($fields) as $i) {
87
            $fields[$i]['canEdit']               = $fields[$i]['field_config'] || $fields[$i]['field_show'] || $fields[$i]['field_edit'];
88
            $fields[$i]['canDelete']             = $fields[$i]['field_config'];
89
            $fields[$i]['fieldtype']             = $fieldtypes[$fields[$i]['field_type']];
90
            $fields[$i]['valuetype']             = $valuetypes[$fields[$i]['field_valuetype']];
91
            $categories[$fields[$i]['cat_id']][] = $fields[$i];
92
            $weights[$fields[$i]['cat_id']][]    = $fields[$i]['field_weight'];
93
        }
94
        //sort fields order in categories
95
        foreach (array_keys($categories) as $i) {
96
            array_multisort($weights[$i], SORT_ASC, array_keys($categories[$i]), SORT_ASC, $categories[$i]);
0 ignored issues
show
SORT_ASC cannot be passed to array_multisort() as the parameter $rest expects a reference. ( Ignorable by Annotation )

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

96
            array_multisort($weights[$i], /** @scrutinizer ignore-type */ SORT_ASC, array_keys($categories[$i]), SORT_ASC, $categories[$i]);
Loading history...
array_keys($categories[$i]) cannot be passed to array_multisort() as the parameter $rest expects a reference. ( Ignorable by Annotation )

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

96
            array_multisort($weights[$i], SORT_ASC, /** @scrutinizer ignore-type */ array_keys($categories[$i]), SORT_ASC, $categories[$i]);
Loading history...
97
        }
98
        ksort($categories);
99
        $GLOBALS['xoopsTpl']->assign('fieldcategories', $categories);
100
        $GLOBALS['xoopsTpl']->assign('token', $GLOBALS['xoopsSecurity']->getTokenHTML());
101
        $template_main = 'admin/suico_admin_fieldslist.tpl';
102
        break;
103
    case 'new':
104
        /** @var Field $obj */
105
        $obj  = $fieldHandler->create();
106
        $form = new FieldForm($obj);
0 ignored issues
show
$obj of type Field is incompatible with the type XoopsModules\Suico\Field expected by parameter $field of XoopsModules\Suico\Form\FieldForm::__construct(). ( Ignorable by Annotation )

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

106
        $form = new FieldForm(/** @scrutinizer ignore-type */ $obj);
Loading history...
107
        $form->display();
108
        break;
109
    case 'edit':
110
        $obj = $fieldHandler->get($_REQUEST['id']);
111
        if (!$obj->getVar('field_config') && !$obj->getVar('field_show') && !$obj->getVar('field_edit')) { //If no configs exist
112
            redirect_header('fieldslist.php', 2, _AM_SUICO_FIELDNOTCONFIGURABLE);
113
        }
114
        $form = new FieldForm($obj);
115
        $form->display();
116
        break;
117
    case 'reorder':
118
        if (!$GLOBALS['xoopsSecurity']->check()) {
119
            redirect_header('fieldslist.php', 3, implode(',', $GLOBALS['xoopsSecurity']->getErrors()));
120
        }
121
        if (isset($_POST['field_ids']) && count($_POST['field_ids']) > 0) {
122
            $oldweight = $_POST['oldweight'];
123
            $oldcat    = $_POST['oldcat'];
124
            $category  = $_POST['category'];
125
            $weight    = $_POST['weight'];
126
            $ids       = [];
127
            foreach ($_POST['field_ids'] as $field_id) {
128
                if ($oldweight[$field_id] != $weight[$field_id] || $oldcat[$field_id] != $category[$field_id]) {
129
                    //if field has changed
130
                    $ids[] = (int)$field_id;
131
                }
132
            }
133
            if (count($ids) > 0) {
134
                $errors = [];
135
                //if there are changed fields, fetch the fieldcategory objects
136
                /** @var FieldHandler $fieldHandler */
137
                $fieldHandler = $helper->getHandler('Field');
138
                $fields       = $fieldHandler->getObjects(new \Criteria('field_id', '(' . implode(',', $ids) . ')', 'IN'), true);
139
                foreach ($ids as $i) {
140
                    $fields[$i]->setVar('field_weight', (int)$weight[$i]);
141
                    $fields[$i]->setVar('cat_id', (int)$category[$i]);
142
                    if (!$fieldHandler->insert($fields[$i])) {
143
//                        $errors = array_merge($errors, $fields[$i]->getErrors());
144
                        $errors[] = $fields[$i]->getErrors();
145
                    }
146
                }
147
                $errors = array_merge([], ...$errors);
148
149
150
                if (0 == count($errors)) {
151
                    //no errors
152
                    redirect_header('fieldslist.php', 2, sprintf(_AM_SUICO_SAVEDSUCCESS, _AM_SUICO_FIELDS));
153
                } else {
154
                    redirect_header('fieldslist.php', 3, implode('<br>', $errors));
155
                }
156
            }
157
        }
158
        break;
159
    case 'save':
160
        if (!$GLOBALS['xoopsSecurity']->check()) {
161
            redirect_header('fieldslist.php', 3, implode(',', $GLOBALS['xoopsSecurity']->getErrors()));
162
        }
163
        $redirect_to_edit = false;
164
        if (isset($_REQUEST['id'])) {
165
            $obj = $fieldHandler->get($_REQUEST['id']);
166
            if (!$obj->getVar('field_config') && !$obj->getVar('field_show') && !$obj->getVar('field_edit')) { //If no configs exist
167
                redirect_header('admin.php', 2, _AM_SUICO_FIELDNOTCONFIGURABLE);
168
            }
169
        } else {
170
            $obj = $fieldHandler->create();
171
            $obj->setVar('field_name', $_REQUEST['field_name']);
172
            $obj->setVar('field_moduleid', $GLOBALS['xoopsModule']->getVar('mid'));
173
            $obj->setVar('field_show', 1);
174
            $obj->setVar('field_edit', 1);
175
            $obj->setVar('field_config', 1);
176
            $redirect_to_edit = true;
177
        }
178
        $obj->setVar('field_title', $_REQUEST['field_title']);
179
        $obj->setVar('field_description', $_REQUEST['field_description']);
180
        if ($obj->getVar('field_config')) {
181
            $obj->setVar('field_type', $_REQUEST['field_type']);
182
            if (isset($_REQUEST['field_valuetype'])) {
183
                $obj->setVar('field_valuetype', $_REQUEST['field_valuetype']);
184
            }
185
            $options = $obj->getVar('field_options');
186
            if (isset($_REQUEST['removeOptions']) && is_array($_REQUEST['removeOptions'])) {
187
                foreach ($_REQUEST['removeOptions'] as $index) {
188
                    unset($options[$index]);
189
                }
190
                $redirect_to_edit = true;
191
            }
192
            if (!empty($_REQUEST['addOption'])) {
193
                foreach ($_REQUEST['addOption'] as $option) {
194
                    if (empty($option['value'])) {
195
                        continue;
196
                    }
197
                    $options[$option['key']] = $option['value'];
198
                    $redirect_to_edit        = true;
199
                }
200
            }
201
            $obj->setVar('field_options', $options);
202
        }
203
        if ($obj->getVar('field_edit')) {
204
            $required = $_REQUEST['field_required'] ?? 0;
205
            $obj->setVar('field_required', $required); //0 = no, 1 = yes
206
            if (isset($_REQUEST['field_maxlength'])) {
207
                $obj->setVar('field_maxlength', $_REQUEST['field_maxlength']);
208
            }
209
            if (isset($_REQUEST['field_default'])) {
210
                $field_default = $obj->getValueForSave($_REQUEST['field_default']);
211
                //Check for multiple selections
212
                if (is_array($field_default)) {
213
                    $obj->setVar('field_default', serialize($field_default));
214
                } else {
215
                    $obj->setVar('field_default', $field_default);
216
                }
217
            }
218
        }
219
        if ($obj->getVar('field_show')) {
220
            $obj->setVar('field_weight', $_REQUEST['field_weight']);
221
            $obj->setVar('cat_id', $_REQUEST['field_category']);
222
        }
223
        if (/*$obj->getVar('field_edit') && */
224
        isset($_REQUEST['step_id'])) {
225
            $obj->setVar('step_id', $_REQUEST['step_id']);
226
        }
227
        if ($fieldHandler->insert($obj)) {
228
            /** @var \XoopsGroupPermHandler $grouppermHandler */
229
            $grouppermHandler = xoops_getHandler('groupperm');
230
            $perm_arr         = [];
231
            if ($obj->getVar('field_show')) {
232
                $perm_arr[] = 'profile_show';
233
                $perm_arr[] = 'profile_visible';
234
            }
235
            if ($obj->getVar('field_edit')) {
236
                $perm_arr[] = 'profile_edit';
237
            }
238
            if ($obj->getVar('field_edit') || $obj->getVar('field_show')) {
239
                $perm_arr[] = 'profile_search';
240
            }
241
            if (count($perm_arr) > 0) {
242
                foreach ($perm_arr as $perm) {
243
                    $criteria = new \CriteriaCompo(new \Criteria('gperm_name', $perm));
244
                    $criteria->add(new \Criteria('gperm_itemid', (int)$obj->getVar('field_id')));
245
                    $criteria->add(new \Criteria('gperm_modid', (int)$GLOBALS['xoopsModule']->getVar('mid')));
246
                    if (isset($_REQUEST[$perm]) && is_array($_REQUEST[$perm])) {
247
                        $perms = $grouppermHandler->getObjects($criteria);
248
                        if (count($perms) > 0) {
249
                            foreach (array_keys($perms) as $i) {
250
                                $groups[$perms[$i]->getVar('gperm_groupid')] = &$perms[$i];
251
                            }
252
                        } else {
253
                            $groups = [];
254
                        }
255
                        foreach ($_REQUEST[$perm] as $groupid) {
256
                            $groupid = (int)$groupid;
257
                            if (!isset($groups[$groupid])) {
258
                                $perm_obj = $grouppermHandler->create();
259
                                $perm_obj->setVar('gperm_name', $perm);
260
                                $perm_obj->setVar('gperm_itemid', (int)$obj->getVar('field_id'));
261
                                $perm_obj->setVar('gperm_modid', $GLOBALS['xoopsModule']->getVar('mid'));
262
                                $perm_obj->setVar('gperm_groupid', $groupid);
263
                                $grouppermHandler->insert($perm_obj);
264
                                unset($perm_obj);
265
                            }
266
                        }
267
                        $removed_groups = array_diff(array_keys($groups), $_REQUEST[$perm]);
268
                        if (count($removed_groups) > 0) {
269
                            $criteria->add(new \Criteria('gperm_groupid', '(' . implode(',', $removed_groups) . ')', 'IN'));
270
                            $grouppermHandler->deleteAll($criteria);
271
                        }
272
                        unset($groups);
273
                    } else {
274
                        $grouppermHandler->deleteAll($criteria);
275
                    }
276
                    unset($criteria);
277
                }
278
            }
279
            $url = $redirect_to_edit ? 'fieldslist.php?op=edit&amp;id=' . $obj->getVar('field_id') : 'fieldslist.php';
280
            redirect_header($url, 3, sprintf(_AM_SUICO_SAVEDSUCCESS, _AM_SUICO_FIELD));
281
        }
282
        echo $obj->getHtmlErrors();
283
        $form = new FieldForm($obj);
284
        $form->display();
285
        break;
286
    case 'delete':
287
        $obj = $fieldHandler->get($_REQUEST['id']);
288
        if (!$obj->getVar('field_config')) {
289
            redirect_header('index.php', 2, _AM_SUICO_FIELDNOTCONFIGURABLE);
290
        }
291
        if (isset($_REQUEST['ok']) && 1 == $_REQUEST['ok']) {
292
            if (!$GLOBALS['xoopsSecurity']->check()) {
293
                redirect_header('fieldslist.php', 3, implode(',', $GLOBALS['xoopsSecurity']->getErrors()));
294
            }
295
            if ($fieldHandler->delete($obj)) {
296
                redirect_header('fieldslist.php', 3, sprintf(_AM_SUICO_DELETEDSUCCESS, _AM_SUICO_FIELD));
297
            } else {
298
                echo $obj->getHtmlErrors();
299
            }
300
        } else {
301
            xoops_confirm(
302
                [
303
                    'ok' => 1,
304
                    'id' => $_REQUEST['id'],
305
                    'op' => 'delete',
306
                ],
307
                $_SERVER['REQUEST_URI'],
308
                sprintf(_AM_SUICO_RUSUREDEL, $obj->getVar('field_title'))
309
            );
310
        }
311
        break;
312
    case 'toggle':
313
        if (isset($_REQUEST['field_id'])) {
314
            $field_id = (int)$_REQUEST['field_id'];
315
            if (isset($_REQUEST['field_required'])) {
316
                $field_required = (int)$_REQUEST['field_required'];
317
                suico_visible_toggle($field_id, $field_required, $helper);
318
            }
319
        }
320
        break;
321
}
322
if (isset($template_main)) {
323
    $GLOBALS['xoopsTpl']->display("db:{$template_main}");
324
}
325
/**
326
 * @param $field_id
327
 * @param $field_required
328
 * @param $helper
329
 */
330
function suico_visible_toggle($field_id, $field_required, $helper): void
331
{
332
    $field_required = (1 == $field_required) ? 0 : 1;
333
    /** @var FieldHandler $fieldHandler */
334
    $fieldHandler = $helper->getHandler('Field');
335
    $obj          = $fieldHandler->get($field_id);
336
    $obj->setVar('field_required', $field_required);
337
    if ($fieldHandler->insert($obj, true)) {
0 ignored issues
show
It seems like $obj can also be of type null; however, parameter $object of XoopsModules\Suico\FieldHandler::insert() does only seem to accept XoopsObject, 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

337
    if ($fieldHandler->insert(/** @scrutinizer ignore-type */ $obj, true)) {
Loading history...
338
        redirect_header('fieldslist.php', 1, _AM_SUICO_REQUIRED_TOGGLE_SUCCESS);
339
    } else {
340
        redirect_header('fieldslist.php', 1, _AM_SUICO_REQUIRED_TOGGLE_FAILED);
341
    }
342
}
343
344
require_once __DIR__ . '/admin_footer.php';
345