Issues (366)

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.

xoops_trust_path/libs/altsys/class/d3utilities.php (6 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
3
/**
4
 * Class d3utilities
5
 */
6
class d3utilities
7
{
8
    public $dirname = ''; // directory name under xoops_trust_path
9
    public $mydirname = ''; // each directory name under xoops_root_path
10
    public $mid = 0; // id of each module instance
11
    public $table = ''; // table with prefix and dirname
12
    public $primary_key = ''; // column for primary_key
13
    public $cols = []; // settings of each columns
14
    public $form_mode = 'new'; // 'new','edit' are available
15
    public $page_name = ''; // controller's name  eg) page=(controller) in URI
16
    public $action_base_hiddens = [];
17
18
    //HACK by domifara
19
20
    //  public function D3Utilities( $mydirname , $table_body , $primary_key , $cols , $page_name , $action_base_hiddens )
21
22
    /**
23
     * d3utilities constructor.
24
     * @param $mydirname
25
     * @param $table_body
26
     * @param $primary_key
27
     * @param $cols
28
     * @param $page_name
29
     * @param $action_base_hiddens
30
     */
31
32
    public function __construct($mydirname, $table_body, $primary_key, $cols, $page_name, $action_base_hiddens)
33
    {
34
        $db = XoopsDatabaseFactory::getDatabaseConnection();
35
36
        $this->dirname = \basename(\dirname(__DIR__));
37
38
        $this->mydirname = $mydirname;
39
40
        $this->table = $db->prefix($mydirname ? $mydirname . '_' . $table_body : $table_body);
41
42
        $this->primary_key = $primary_key;
43
44
        $this->cols = $cols;
45
46
        $module_handler = xoops_getHandler('module');
47
48
        $module = $module_handler->getByDirname($this->mydirname);
49
50
        if (!empty($module)) {
51
            $this->mid = (int)$module->getVar('mid');
52
        }
53
54
        $this->page_name = $page_name;
55
56
        $this->action_base_hiddens = $action_base_hiddens;
57
    }
58
59
    /**
60
     * @param $name
61
     * @return mixed
62
     */
63
64
    public function get_language_constant($name)
65
    {
66
        return constant(mb_strtoupper('_MD_A_' . $this->dirname . '_' . $this->page_name . '_' . $name));
67
    }
68
69
    /**
70
     * @param $value
71
     * @param $col
72
     * @return string
73
     */
74
75
    public function get_set4sql($value, $col)
76
    {
77
        switch ($col['type']) {
78
            case 'text':
79 View Code Duplication
            case 'blob':
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
80
                $length = empty($col['length']) ? 65535 : (int)$col['length'];
81
82
                return "`{$col['name']}`='" . addslashes(xoops_substr($value, 0, $length)) . "'";
83
            case 'char':
84
            case 'varchar':
85 View Code Duplication
            case 'string':
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
86
                $length = empty($col['length']) ? 255 : (int)$col['length'];
87
88
                return "`{$col['name']}`='" . addslashes(xoops_substr($value, 0, $length)) . "'";
89
            case 'int':
90
            case 'integer':
91
                $value = (int)$value;
92
                if (!empty($col['max'])) {
93
                    $value = min($value, (int)$col['max']);
94
                }
95
                if (!empty($col['min'])) {
96
                    $value = max($value, (int)$col['min']);
97
                }
98
99
                return "`{$col['name']}`=$value";
100
        }
101
    }
102
103
    // single update or insert
104
105
    /**
106
     * @return array
107
     */
0 ignored issues
show
Should the return type not be array<integer|string>|null?

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...
108
109
    public function insert()
110
    {
111
        $db = XoopsDatabaseFactory::getDatabaseConnection();
112
113
        $id = $this->init_default_values();
114
115
        $set4sql = '';
116
117 View Code Duplication
        foreach ($this->cols as $col) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
118
            if (empty($col['edit_edit'])) {
119
                continue;
120
            }
121
122
            if ($col['name'] == $this->primary_key) {
123
                continue;
124
            }
125
126
            $set4sql .= $this->get_set4sql(@$_POST[$col['name']], $col) . ',';
127
        }
128
129
        if (!empty($set4sql)) {
130
            if ($id > 0) {
131
                // UPDATE
132
133
                $db->queryF("UPDATE $this->table SET " . mb_substr($set4sql, 0, -1) . " WHERE $this->primary_key='" . addslashes($id) . "'");
134
135
                return [$id, 'update'];
136
            }
137
138
            // INSERT
139
140
            $db->queryF("INSERT INTO $this->table SET " . mb_substr($set4sql, 0, -1));
141
142
            return [$db->getInsertId(), 'insert'];
143
        }
144
    }
145
146
    // multiple update
147
148
    /**
149
     * @return array
150
     */
151
152
    public function update()
153
    {
154
        $db = XoopsDatabaseFactory::getDatabaseConnection();
155
156
        // search appropriate column for getting primary_key
157
158
        foreach ($this->cols as $col) {
159
            if (in_array(@$col['list_edit'], ['text', 'textarea', 'hidden'], true)) {
160
                $column4key = $col['name'];
161
162
                break;
163
            }
164
        }
165
166
        if (empty($column4key)) {
167
            $column4key = $this->cols[0]['name'];
168
        }
169
170
        $ret = [];
171
172
        foreach (array_keys($_POST[$column4key]) as $id) {
173
            $id = (int)$id;    // primary_key should be 'integer'
174
175
            $set4sql = '';
176
177 View Code Duplication
            foreach ($this->cols as $col) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
178
                if (empty($col['list_edit'])) {
179
                    continue;
180
                }
181
182
                if ($col['name'] == $this->primary_key) {
183
                    continue;
184
                }
185
186
                $set4sql .= $this->get_set4sql(@$_POST[$col['name']][$id], $col) . ',';
187
            }
188
189
            if (!empty($set4sql)) {
190
                $result = $db->query("SELECT * FROM $this->table WHERE $this->primary_key=$id");
191
192
                if (1 == $db->getRowsNum($result)) {
193
                    $db->queryF("UPDATE $this->table SET " . mb_substr($set4sql, 0, -1) . " WHERE $this->primary_key=$id");
194
195
                    if (1 == $db->getAffectedRows()) {
196
                        $ret[$id] = $db->fetchArray($result);
197
                    }
198
                }
199
            }
200
        }
201
202
        return $ret;
203
    }
204
205
    /**
206
     * @param bool $delete_comments
207
     * @param bool $delete_notifications
208
     * @return array
209
     */
210
211
    public function delete($delete_comments = false, $delete_notifications = false)
212
    {
213
        $db = XoopsDatabaseFactory::getDatabaseConnection();
214
215
        $ret = [];
216
217
        foreach (array_keys($_POST['admin_main_checkboxes']) as $id) {
218
            $id = (int)$id;    // primary_key should be 'integer'
219
220
            $result = $db->query("SELECT * FROM $this->table WHERE $this->primary_key=$id");
221
222
            if (1 == $db->getRowsNum($result)) {
223
                $ret[$id] = $db->fetchArray($result);
224
225
                $db->queryF("DELETE FROM $this->table WHERE $this->primary_key=$id");
226
227
                if ($delete_comments) {
228
                    // remove comments
229
230
                    $db->queryF('DELETE FROM ' . $db->prefix('xoopscomments') . " WHERE com_modid=$this->mid AND com_itemid=$id");
231
                }
232
233
                if ($delete_notifications) {
234
                    // remove notifications
235
236
                    $db->queryF('DELETE FROM ' . $db->prefix('xoopsnotifications') . " WHERE not_modid=$this->mid AND not_itemid=$id");
237
                }
238
            }
239
        }
240
241
        return $ret;
242
    }
243
244
    /**
245
     * @return int
246
     */
247
248
    public function init_default_values()
249
    {
250
        $db = XoopsDatabaseFactory::getDatabaseConnection();
251
252
        if (@$_GET['id']) {
253
            $id = \Xmf\Request::getInt('id', 0, 'GET');
254
255
            $rs = $db->query("SELECT * FROM $this->table WHERE $this->primary_key=$id");
256
257
            if (1 == $db->getRowsNum($rs)) {
258
                $row = $db->fetchArray($rs);
259
260
                foreach (array_keys($this->cols) as $key) {
261
                    if (empty($this->cols[$key]['edit_show'])) {
262
                        continue;
263
                    }
264
265
                    $this->cols[$key]['default_value'] = $row[$this->cols[$key]['name']];
266
                }
267
268
                $this->form_mode = 'edit';
269
270
                return $id;
271
            }
272
        }
273
274
        $this->form_mode = 'new';
275
276
        return 0;
277
    }
278
279
    /**
280
     * @return array
281
     */
282
283
    public function get_view_edit()
284
    {
285
        $id = $this->init_default_values();
286
287
        $lines = [];
288
289
        foreach ($this->cols as $col) {
290
            if (empty($col['edit_show'])) {
291
                continue;
292
            }
293
294
            if (!isset($col['default_value'])) {
295
                switch ($col['type']) {
296
                    case 'int':
297
                    case 'integer':
298
                        $col['default_value'] = 0;
299
                        break;
300
                    default:
301
                        $col['default_value'] = '';
302
                        break;
303
                }
304
            }
305
306
            switch ($col['edit_edit']) {
307
                case 'checkbox':
308
                    $checked = empty($col['default_value']) ? '' : "checked='checked'";
309
                    $value = empty($col['checkbox_value']) ? 1 : htmlspecialchars($col['checkbox_value'], ENT_QUOTES);
310
311
                    $lines[$col['name']] = "<input type='checkbox' name='{$col['name']}' value='$value' $checked />";
312
                    break;
313
                case 'text':
314
                default:
315
                    $size = empty($col['edit_size']) ? 32 : (int)$col['edit_size'];
316
                    $length = empty($col['length']) ? 255 : (int)$col['length'];
317
                    $lines[$col['name']] = "<input type='text' name='{$col['name']}' size='$size' maxlength='$length' value='" . htmlspecialchars($col['default_value'], ENT_QUOTES) . "' />";
318
                    break;
319
                case false:
0 ignored issues
show
case false: $lines[$...ENT_QUOTES); break; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
320
                    $lines[$col['name']] = htmlspecialchars($col['default_value'], ENT_QUOTES);
321
                    break;
322
            }
323
        }
324
325
        return [$id, $lines];
326
    }
327
328
    /**
329
     * @param $controllers
330
     * @return string
331
     */
332
333
    public function get_control_form($controllers)
334
    {
335
        $hiddens = '';
336
337
        foreach ($this->action_base_hiddens as $key => $val) {
338
            $key4disp = htmlspecialchars($key, ENT_QUOTES);
339
340
            $val4disp = htmlspecialchars($val, ENT_QUOTES);
341
342
            $hiddens .= "<input type='hidden' name='$key4disp' value='$val4disp' />\n";
343
        }
344
345
        $controllers_html = '';
346
347
        foreach ($controllers as $type => $body) {
348
            if ('num' == $type) {
349
                $controllers_html .= $this->get_select('num', $body, $GLOBALS['num']);
350
            }
351
        }
352
353
        return "
354
            <form action='' method='get' name='admin_control' id='admin_control'>
355
                $hiddens
356
                $controllers_html
357
                <input type='submit' value='" . _SUBMIT . "' />
358
            </form>\n";
359
    }
360
361
    /**
362
     * @param $name
363
     * @param $options
364
     * @param $current_value
365
     * @return string
366
     */
367
368
    public function get_select($name, $options, $current_value)
369
    {
370
        $ret = "<select name='" . htmlspecialchars($name, ENT_QUOTES) . "'>\n";
371
372
        foreach ($options as $key => $val) {
373
            $selected = $val == $current_value ? "selected='selected'" : '';
374
375
            $ret .= "<option value='" . htmlspecialchars($key, ENT_QUOTES) . "' $selected>" . htmlspecialchars($val, ENT_QUOTES) . "</option>\n";
376
        }
377
378
        $ret .= "</select>\n";
379
380
        return $ret;
381
    }
382
}
383