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.

class/AudioHandler.php (4 issues)

1
<?php declare(strict_types=1);
2
3
namespace XoopsModules\Suico;
4
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
10
 This program is distributed in the hope that it will be useful,
11
 but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
*/
14
15
/**
16
 * @category        Module
17
 * @copyright       {@link https://xoops.org/ XOOPS Project}
18
 * @license         GNU GPL 2.0 or later (https://www.gnu.org/licenses/gpl-2.0.html)
19
 * @author          Bruno Barthez, Marcello Brandão aka  Suico, Mamba, LioMJ  <https://xoops.org>
20
 */
21
22
use CriteriaCompo;
23
use CriteriaElement;
24
use Xmf\Request;
25
use XoopsDatabase;
26
use XoopsObject;
27
use XoopsPersistableObjectHandler;
28
use XoopsModules\Suico\{
29
    Helper
0 ignored issues
show
This use statement conflicts with another class in this namespace, XoopsModules\Suico\Helper. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
30
};
31
/** @var Helper $helper */
32
require_once XOOPS_ROOT_PATH . '/kernel/object.php';
33
require_once XOOPS_ROOT_PATH . '/class/uploader.php';
34
35
/**
36
 * AudioHandler class.
37
 * This class provides simple mechanism for suico_audio object
38
 */
39
class AudioHandler extends XoopsPersistableObjectHandler
40
{
41
    public $isAdmin;
42
    public $helper;
43
44
    /**
45
     * Constructor
46
     * @param \XoopsDatabase|null $xoopsDatabase
47
     * @param Helper|null $helper
48
     */
49
    public function __construct(
50
        ?XoopsDatabase $xoopsDatabase = null,
51
        $helper = null
52
    ) {
53
        /** @var Helper $this- >helper */
54
        if (null === $helper) {
55
            $this->helper = Helper::getInstance();
56
        } else {
57
            $this->helper = $helper;
58
        }
59
        $this->isAdmin = $this->helper->isUserAdmin();
60
        parent::__construct($xoopsDatabase, 'suico_audios', Audio::class, 'audio_id', 'title');
61
    }
62
63
    /**
64
     * @param bool $isNew
65
     *
66
     * @return XoopsObject
67
     */
68
    public function create($isNew = true)
69
    {
70
        $obj = parent::create($isNew);
71
        if ($isNew) {
72
            $obj->setNew();
73
        } else {
74
            $obj->unsetNew();
75
        }
76
        $obj->helper = $this->helper;
77
78
        return $obj;
79
    }
80
81
    /**
82
     * retrieve a suico_audio
83
     *
84
     * @param int|null $id of the suico_audio
85
     * @return false|\XoopsModules\Suico\Audio reference to the {@link suico_audio} object, FALSE if failed
86
     */
87
    public function get2(
88
        $id = null
89
        //        $fields = null
90
    )
91
    {
92
        $sql = 'SELECT * FROM ' . $this->db->prefix('suico_audios') . ' WHERE audio_id=' . $id;
93
        if (!$result = $this->db->query($sql)) {
94
            return false;
95
        }
96
        $numrows = $this->db->getRowsNum($result);
97
        if (1 === $numrows) {
98
            $suicoAudio = new Audio();
99
            $suicoAudio->assignVars($this->db->fetchArray($result));
100
101
            return $suicoAudio;
102
        }
103
104
        return false;
105
    }
106
107
    /**
108
     * insert a new Audio in the database
109
     *
110
     * @param XoopsObject $object reference to the {@link suico_audio}
111
     *                                 object
112
     * @param bool        $force
113
     * @return bool FALSE if failed, TRUE if already present and unchanged or successful
114
     */
115
    public function insert2(
116
        XoopsObject $object,
117
        $force = false
118
    ) {
119
        global $xoopsConfig;
120
        if (Audio::class !== \get_class($object)) {
121
            return false;
122
        }
123
        if (!$object->isDirty()) {
124
            return true;
125
        }
126
        if (!$object->cleanVars()) {
127
            return false;
128
        }
129
        foreach ($object->cleanVars as $k => $v) {
130
            ${$k} = $v;
131
        }
132
        $audio_id     = Request::getString('audio_id', '', 'POST');
133
        $uid_owner    = Request::getInt('audio_id', 0, 'POST');
134
        $title        = Request::getString('title', '', 'POST');
135
        $author       = Request::getString('author', '', 'POST');
136
        $description  = Request::getText('description', '', 'POST');
137
        $filename     = Request::getString('filename', '', 'POST');
138
        $date_created = Request::getString('date_created', \time(), 'POST');
139
        $date_updated = Request::getString('date_updated', \time(), 'POST');
140
        //        $now = 'date_add(now(), interval ' . $xoopsConfig['server_TZ'] . ' hour)';
141
        if ($object->isNew()) {
142
            // adding / modifying a suico_audio
143
            $object = new Audio();
144
            $format      = 'INSERT INTO %s (audio_id, title, author, description, filename, uid_owner, date_created, date_updated)';
145
            $format      .= ' VALUES (%u, %s, %s, %s, %s, %u, %s, %s)';
146
            $sql         = \sprintf(
147
                $format,
148
                $this->db->prefix('suico_audios'),
149
                $audio_id,
150
                $this->db->quoteString($author),
151
                $this->db->quoteString($title),
152
                $this->db->quoteString($description),
153
                $this->db->quoteString($filename),
154
                $uid_owner,
155
                $date_created,
156
                $date_updated
157
            );
158
            $force       = true;
159
        } else {
160
            $format = 'UPDATE %s SET ';
161
            $format .= 'audio_id=%u, title=%s, author=%s, filename=%s, description=%s,uid_owner=%u, date_created=%s, date_updated=%s';
162
            $format .= ' WHERE audio_id = %u';
163
            $sql    = \sprintf(
164
                $format,
165
                $this->db->prefix('suico_audios'),
166
                $audio_id,
167
                $this->db->quoteString($title),
168
                $this->db->quoteString($author),
169
                $this->db->quoteString($filename),
170
                $uid_owner,
171
                $date_created,
172
                $date_updated,
173
                $audio_id
174
            );
175
        }
176
        if ($force) {
177
            $result = $this->db->queryF($sql);
178
        } else {
179
            $result = $this->db->query($sql);
180
        }
181
        if (!$result) {
182
            return false;
183
        }
184
        if (empty($audio_id)) {
185
            $audio_id = $this->db->getInsertId();
186
        }
187
        $object->assignVar('audio_id', $audio_id);
188
189
        return true;
190
    }
191
192
    /**
193
     * delete a suico_audio from the database
194
     *
195
     * @param XoopsObject $object reference to the suico_audio to delete
196
     * @param bool        $force
197
     * @return bool FALSE if failed.
198
     */
199
    public function delete(
200
        XoopsObject $object,
201
        $force = false
202
    ) {
203
        if (Audio::class !== \get_class($object)) {
204
            return false;
205
        }
206
        $sql = \sprintf(
207
            'DELETE FROM %s WHERE audio_id = %u',
208
            $this->db->prefix('suico_audios'),
209
            (int)$object->getVar('audio_id')
210
        );
211
        if ($force) {
212
            $result = $this->db->queryF($sql);
213
        } else {
214
            $result = $this->db->query($sql);
215
        }
216
        if (!$result) {
217
            return false;
218
        }
219
220
        return true;
221
    }
222
223
    /**
224
     * retrieve suico_audios from the database
225
     *
226
     * @param \CriteriaElement|\CriteriaCompo|null $criteria {@link \CriteriaElement} conditions to be met
227
     * @param bool                                 $id_as_key       use the UID as key for the array?
228
     * @param bool                                 $as_object
229
     * @return array array of {@link suico_audio} objects
230
     */
231
    public function &getObjects(
232
        ?CriteriaElement $criteria = null,
233
        $id_as_key = false,
234
        $as_object = true
235
    ) {
236
        $ret   = [];
237
        $start = 0;
238
        $limit = 0;
239
        $sql   = 'SELECT * FROM ' . $this->db->prefix('suico_audios');
240
        if (isset($criteria) && is_subclass_of($criteria, 'CriteriaElement')) {
241
            $sql .= ' ' . $criteria->renderWhere();
0 ignored issues
show
The method renderWhere() does not exist on CriteriaElement. Did you maybe mean render()? ( Ignorable by Annotation )

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

241
            $sql .= ' ' . $criteria->/** @scrutinizer ignore-call */ renderWhere();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
242
            if ('' !== $criteria->getSort()) {
243
                $sql .= ' ORDER BY ' . $criteria->getSort() . ' ' . $criteria->getOrder();
244
            }
245
            $limit = $criteria->getLimit();
246
            $start = $criteria->getStart();
247
        }
248
        $result = $this->db->query($sql, $limit, $start);
249
        if (!$result) {
250
            return $ret;
251
        }
252
        while (false !== ($myrow = $this->db->fetchArray($result))) {
253
            $suicoAudio = new Audio();
254
            $suicoAudio->assignVars($myrow);
255
            if ($id_as_key) {
256
                $ret[$myrow['audio_id']] = &$suicoAudio;
257
            } else {
258
                $ret[] = &$suicoAudio;
259
            }
260
            unset($suicoAudio);
261
        }
262
263
        return $ret;
264
    }
265
266
    /**
267
     * count suico_audios matching a condition
268
     *
269
     * @param CriteriaElement|CriteriaCompo|null $criteria {@link \CriteriaElement} to match
270
     * @return int count of suico_audios
271
     */
272
    public function getCount(
273
        ?CriteriaElement $criteria = null
274
    ) {
275
        $sql = 'SELECT COUNT(*) FROM ' . $this->db->prefix('suico_audios');
276
        if (isset($criteria) && is_subclass_of($criteria, 'CriteriaElement')) {
277
            $sql .= ' ' . $criteria->renderWhere();
278
        }
279
        $result = $this->db->query($sql);
280
        if (!$result) {
281
            return 0;
282
        }
283
        [$count] = $this->db->fetchRow($result);
284
285
        return (int)$count;
286
    }
287
288
    /**
289
     * delete suico_audios matching a set of conditions
290
     *
291
     * @param CriteriaElement|CriteriaCompo|null $criteria {@link \CriteriaElement}
292
     * @param bool                               $force
293
     * @param bool                               $asObject
294
     * @return bool FALSE if deletion failed
295
     */
296
    public function deleteAll(
297
        ?CriteriaElement $criteria = null,
298
        $force = true,
299
        $asObject = false
300
    ) {
301
        $sql = 'DELETE FROM ' . $this->db->prefix('suico_audios');
302
        if (isset($criteria) && is_subclass_of($criteria, 'CriteriaElement')) {
303
            $sql .= ' ' . $criteria->renderWhere();
304
        }
305
        if (!$result = $this->db->query($sql)) {
0 ignored issues
show
The assignment to $result is dead and can be removed.
Loading history...
306
            return false;
307
        }
308
309
        return true;
310
    }
311
312
    /**
313
     * Upload the file and Save into database
314
     *
315
     * @param string $title       A litle description of the file
316
     * @param string $path_upload The path to where the file should be uploaded
317
     * @param string $author      the author of the music or audio file
318
     * @param        $maxfilebytes
319
     * @param        $description
320
     * @return bool FALSE if upload fails or database fails
321
     */
322
    public function receiveAudio(
323
        $title,
324
        $path_upload,
325
        $author,
326
        $maxfilebytes,
327
        $description
328
    ) {
329
        global $xoopsUser, $xoopsDB, $_POST, $_FILES;
330
        //busca id do user logado
331
        $uid = $xoopsUser->getVar('uid');
332
        //create a hash so it does not erase another file
333
        //$hash1 = date();
334
        //$hash = substr($hash1,0,4);
335
        // mimetypes and settings put this in admin part later
336
        $allowed_mimetypes = [
337
            'audio/mp3',
338
            'audio/x-mp3',
339
            'audio/mpeg',
340
        ];
341
        $maxfilesize       = $maxfilebytes;
342
        $uploadDir         = $path_upload;
343
        // create the object to upload
344
        $uploader = new \XoopsMediaUploader(
345
            $uploadDir,
346
            $allowed_mimetypes,
347
            $maxfilesize
348
        );
349
        // fetch the media
350
        if ($uploader->fetchMedia((Request::getArray('xoops_upload_file', '', 'POST')[0]))) {
351
            //lets create a name for it
352
            $uploader->setPrefix('aud_' . $uid . '_');
353
            //now let s upload the file
354
            if (!$uploader->upload()) {
355
                // if there are errors lets return them
356
                echo '<div style="color:#FF0000; background-color:#FFEAF4; border-color:#FF0000; border-width:thick; border-style:solid; text-align:center"><p>' . $uploader->getErrors() . '</p></div>';
357
358
                return false;
359
            }
360
            // now let s create a new object audio and set its variables
361
            //echo "passei aqui";
362
            $audio = $this->create();
363
            $audio->setVar('uid_owner', $xoopsUser->getVar('uid'));
364
            $audio->setVar('title', $title);
365
            $audio->setVar('author', $author);
366
            $audio->setVar('description', $description);
367
            $audio->setVar(
368
                'filename',
369
                $uploader->getSavedFileName()
370
            );
371
            $audio->setVar('date_created', \time());
372
            $audio->setVar('date_updated', \time());
373
            $this->insert($audio);
374
            $saved_destination = $uploader->getSavedDestination();
0 ignored issues
show
The assignment to $saved_destination is dead and can be removed.
Loading history...
375
            //print_r($_FILES);
376
        } else {
377
            echo '<div style="color:#FF0000; background-color:#FFEAF4; border-color:#FF0000; border-width:thick; border-style:solid; text-align:center"><p>' . $uploader->getErrors() . '</p></div>';
378
379
            return false;
380
        }
381
382
        return true;
383
    }
384
}
385