Issues (89)

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

1
<?php declare(strict_types=1);
2
3
namespace XoopsModules\Contact;
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
use Xmf\Request;
16
use XoopsPersistableObjectHandler;
17
18
/**
19
 * Contact module
20
 *
21
 * @copyright     XOOPS Project (https://xoops.org)
22
 * @license       https://www.fsf.org/copyleft/gpl.html GNU public license
23
 * @author        Kazumi Ono (aka Onokazu)
24
 * @author        Trabis <[email protected]>
25
 * @author        Hossein Azizabadi (AKA Voltan)
26
 * @author        Mirza (AKA Bleekk)
27
 */
28
29
/**
30
 * Class ContactHandler
31
 */
32
class ContactHandler extends XoopsPersistableObjectHandler
33
{
34
    /**
35
     * ContactHandler constructor.
36
     */
37
    public function __construct(\XoopsDatabase $db = null)
38
    {
39
        parent::__construct($db, 'contact', Contact::class, 'contact_id', 'contact_mail');
40
    }
41
42
    /**
43
     * Get variables passed by GET or POST method
44
     * @param        $global
45
     * @param        $key
46
     * @param string $default
47
     * @param string $type
48
     * @return false|int|mixed|string
49
     */
50
    /*
51
    public function contactCleanVars(&$global, $key, $default = '', $type = 'int')
52
    {
53
        switch ($type) {
54
            case 'array':
55
                $ret = (isset($global[$key]) && is_array($global[$key])) ? $global[$key] : $default;
56
                break;
57
            case 'date':
58
                $ret = isset($global[$key]) ? strtotime($global[$key]) : $default;
59
                break;
60
            case 'string':
61
                            if(defined('FILTER_SANITIZE_ADD_SLASHES')){
62
                $ret = isset($global[$key]) ? filter_var($global[$key], FILTER_SANITIZE_ADD_SLASHES) : $default;
63
            } else {
64
                $ret = isset($global[$key]) ? filter_var($global[$key], FILTER_SANITIZE_MAGIC_QUOTES) : $default;
65
            }
66
                break;
67
            case 'mail':
68
                $ret = isset($global[$key]) ? filter_var($global[$key], FILTER_VALIDATE_EMAIL) : $default;
69
                break;
70
            case 'url':
71
                $ret = isset($global[$key]) ? filter_var($global[$key], FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED) : $default;
72
                break;
73
            case 'ip':
74
                $ret = isset($global[$key]) ? filter_var($global[$key], FILTER_VALIDATE_IP) : $default;
75
                break;
76
            case 'amp':
77
                $ret = isset($global[$key]) ? filter_var($global[$key], FILTER_FLAG_ENCODE_AMP) : $default;
78
                break;
79
            case 'text':
80
                $ret = isset($global[$key]) ? htmlentities($global[$key], ENT_QUOTES, 'UTF-8') : $default;
81
                break;
82
            case 'platform':
83
                $ret = isset($global[$key]) ? $this->contactPlatform($global[$key]) : $this->contactPlatform($default);
84
                break;
85
            case 'type':
86
                $ret = isset($global[$key]) ? $this->contactType($global[$key]) : $this->contactType($default);
87
                break;
88
            case 'int':
89
            default:
90
                $ret = isset($global[$key]) ? filter_var($global[$key], FILTER_SANITIZE_NUMBER_INT) : $default;
91
                break;
92
        }
93
        if ($ret === false) {
94
            return $default;
95
        }
96
97
        return $ret;
98
    }
99
*/
100
101
    /**
102
     * @return array
103
     */
104
    public function contactInfoProcessing(): array
105
    {
106
        $contact                       = [];
107
        $contact['contact_cid']        = Request::getInt('contact_id', 0, 'POST');
108
        $contact['contact_uid']        = Request::getInt('contact_uid', 0, 'POST');
109
        $contact['contact_name']       = Request::getString('contact_name', '', 'POST');
110
        $contact['contact_nameto']     = Request::getString('contact_nameto', '', 'POST');
111
        $contact['contact_subject']    = Request::getString('contact_subject', '', 'POST');
112
        $contact['contact_mail']       = Request::getString('contact_mail', '', 'POST');
113
        $contact['contact_mailto']     = Request::getEmail('contact_mailto', '', 'POST');
114
        $contact['contact_url']        = Request::getUrl('contact_url', '', 'POST');
115
        $contact['contact_create']     = \time();
116
        $contact['contact_icq']        = Request::getString('contact_icq', '', 'POST');
117
        $contact['contact_skype']      = Request::getString('contact_skype', '', 'POST');
118
        $contact['contact_company']    = Request::getString('contact_company', '', 'POST');
119
        $contact['contact_location']   = Request::getString('contact_location', '', 'POST');
120
        $contact['contact_phone']      = Request::getString('contact_phone', '', 'int');
121
        $contact['contact_department'] = Request::getString('contact_department', \xoops_getModuleOption('contact_recipient_std', 'contact'), 'POST');
0 ignored issues
show
Deprecated Code introduced by
The function xoops_getModuleOption() has been deprecated. ( Ignorable by Annotation )

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

121
        $contact['contact_department'] = Request::getString('contact_department', /** @scrutinizer ignore-deprecated */ \xoops_getModuleOption('contact_recipient_std', 'contact'), 'POST');
Loading history...
122
        $contact['contact_ip']         = \getenv('REMOTE_ADDR');
123
        $contact['contact_message']    = Request::getText('contact_message', '', 'POST');
124
        $contact['contact_address']    = Request::getString('contact_address', '', 'POST');
125
        $contact['contact_platform']   = Request::getString('contact_platform', 'Web', 'POST');
126
        $contact['contact_type']       = Request::getString('contact_type', 'Contact', 'POST');
127
        $contact['contact_reply']      = Request::getInt('contact_reply', 0, 'POST');
128
129
        return $contact;
130
    }
131
132
    /**
133
     * @param $contact
134
     * @return string
135
     */
136
    public function contactSendMail($contact): string
137
    {
138
        $xoopsMailer = \xoops_getMailer();
139
        $xoopsMailer->useMail();
140
        $xoopsMailer->setToEmails($this->contactToEmails($contact['contact_department']));
141
        $xoopsMailer->setFromEmail($contact['contact_mail']);
142
        $xoopsMailer->setFromName(\html_entity_decode($contact['contact_name'], \ENT_QUOTES, 'UTF-8'));
143
144
        $info          = '';
145
        $subjectPrefix = '';
146
        if ($GLOBALS['xoopsModuleConfig']['form_dept'] && $GLOBALS['xoopsModuleConfig']['subject_prefix'] && $GLOBALS['xoopsModuleConfig']['contact_dept']) {
147
            $subjectPrefix = '[' . $GLOBALS['xoopsModuleConfig']['prefix_text'] . ' ' . $contact['contact_department'] . ']: ';
148
            $info          .= _MD_CONTACT_DEPARTMENT . ': ' . $contact['contact_department'] . "\n";
149
        }
150
        $xoopsMailer->setSubject($subjectPrefix . \html_entity_decode($contact['contact_subject'], \ENT_QUOTES, 'UTF-8'));
151
152
        if ($contact['contact_url']) {
153
            $info .= _MD_CONTACT_URL . ': ' . $contact['contact_url'] . "\n";
154
        }
155
        if ($contact['contact_icq']) {
156
            $info .= _MD_CONTACT_ICQ . ': ' . $contact['contact_icq'] . "\n";
157
        }
158
        if ($contact['contact_skype']) {
159
            $info .= _MD_CONTACT_SKYPE . ': ' . $contact['contact_skype'] . "\n";
160
        }
161
        if ($contact['contact_phone']) {
162
            $info .= _MD_CONTACT_PHONE . ': ' . $contact['contact_phone'] . "\n";
163
        }
164
        if ($contact['contact_company']) {
165
            $info .= _MD_CONTACT_COMPANY . ': ' . $contact['contact_company'] . "\n";
166
        }
167
        if ($contact['contact_location']) {
168
            $info .= _MD_CONTACT_LOCATION . ': ' . $contact['contact_location'] . "\n";
169
        }
170
        if ($contact['contact_address']) {
171
            $info .= _MD_CONTACT_ADDRESS . ': ' . $contact['contact_address'] . "\n";
172
        }
173
        if ('' !== $info) {
174
            $info = "\n" . $info . "\n";
175
        }
176
177
        $body = \str_replace('{BODY}', \html_entity_decode($contact['contact_message'], \ENT_QUOTES, 'UTF-8'), \_MD_CONTACT_MAIL_BODY);
178
        $body = \str_replace('{INFO}', $info, $body);
179
        $body = \str_replace('{WEBSITE}', XOOPS_URL, $body);
180
181
        $xoopsMailer->setBody($body);
182
        if ($xoopsMailer->send()) {
183
            $message = _MD_CONTACT_MES_SEND;
184
        } else {
185
            $message = $xoopsMailer->getErrors();
186
        }
187
188
        return $message;
189
    }
190
191
    /**
192
     * @param $contact
193
     * @return string
194
     */
195
    public function contactSendMailConfirm($contact): string
196
    {
197
        $xoopsMailer = \xoops_getMailer();
198
        $xoopsMailer->useMail();
199
        $xoopsMailer->setToEmails($contact['contact_mail']);
200
        $xoopsMailer->setFromEmail(\xoops_getModuleOption('contact_recipient_std', 'contact'));
0 ignored issues
show
Deprecated Code introduced by
The function xoops_getModuleOption() has been deprecated. ( Ignorable by Annotation )

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

200
        $xoopsMailer->setFromEmail(/** @scrutinizer ignore-deprecated */ \xoops_getModuleOption('contact_recipient_std', 'contact'));
Loading history...
201
        $xoopsMailer->setFromName(\html_entity_decode($GLOBALS['xoopsConfig']['sitename'], \ENT_QUOTES, 'UTF-8'));
202
203
        $xoopsMailer->setSubject(_MD_CONTACT_MAILCONFIRM_SUBJECT);
204
205
        $info = '';
206
        if ($contact['contact_url']) {
207
            $info .= _MD_CONTACT_URL . ': ' . $contact['contact_url'] . "\n";
208
        }
209
        if ($contact['contact_icq']) {
210
            $info .= _MD_CONTACT_ICQ . ': ' . $contact['contact_icq'] . "\n";
211
        }
212
        if ($contact['contact_skype']) {
213
            $info .= _MD_CONTACT_SKYPE . ': ' . $contact['contact_skype'] . "\n";
214
        }
215
        if ($contact['contact_phone']) {
216
            $info .= _MD_CONTACT_PHONE . ': ' . $contact['contact_phone'] . "\n";
217
        }
218
        if ($contact['contact_company']) {
219
            $info .= _MD_CONTACT_COMPANY . ': ' . $contact['contact_company'] . "\n";
220
        }
221
        if ($contact['contact_location']) {
222
            $info .= _MD_CONTACT_LOCATION . ': ' . $contact['contact_location'] . "\n";
223
        }
224
        if ($contact['contact_address']) {
225
            $info .= _MD_CONTACT_ADDRESS . ': ' . $contact['contact_address'] . "\n";
226
        }
227
        if ('' !== $info) {
228
            $info = "\n" . $info . "\n";
229
        }
230
231
        $body = \str_replace('{NAME}', \html_entity_decode($contact['contact_name'], \ENT_QUOTES, 'UTF-8'), _MD_CONTACT_MAILCONFIRM_BODY);
232
        $body = \str_replace('{SUBJECT}', \html_entity_decode($contact['contact_subject'], \ENT_QUOTES, 'UTF-8'), $body);
233
        $body = \str_replace('{INFO}', $info, $body);
234
        $body = \str_replace('{BODY}', \html_entity_decode($contact['contact_message'], \ENT_QUOTES, 'UTF-8'), $body);
235
        $xoopsMailer->setBody($body);
236
        if ($xoopsMailer->send()) {
237
            $message = _MD_CONTACT_MES_SEND;
238
        } else {
239
            $message = $xoopsMailer->getErrors();
240
        }
241
242
        return $message;
243
    }
244
245
    /**
246
     * @param $contact
247
     * @return string
248
     */
249
    public function contactReplyMail($contact): string
250
    {
251
        $xoopsMailer = \xoops_getMailer();
252
        $xoopsMailer->useMail();
253
        $xoopsMailer->setToEmails($contact['contact_mailto']);
254
        $xoopsMailer->setFromEmail($contact['contact_mail']);
255
        $xoopsMailer->setFromName($contact['contact_name']);
256
        $xoopsMailer->setSubject($contact['contact_subject']);
257
        $xoopsMailer->setBody($contact['contact_message']);
258
        if ($xoopsMailer->send()) {
259
            $message = _MD_CONTACT_MES_SEND;
260
        } else {
261
            $message = $xoopsMailer->getErrors();
262
        }
263
264
        return $message;
265
    }
266
267
    /**
268
     * @param null $department
269
     * @return array
270
     */
271
    public function contactToEmails($department = null): array
272
    {
273
        //        global $xoopsConfig;
274
        $department_mail[] = \xoops_getModuleOption('contact_recipient_std', 'contact');
0 ignored issues
show
Deprecated Code introduced by
The function xoops_getModuleOption() has been deprecated. ( Ignorable by Annotation )

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

274
        $department_mail[] = /** @scrutinizer ignore-deprecated */ \xoops_getModuleOption('contact_recipient_std', 'contact');
Loading history...
275
        if (!empty($department)) {
276
            $departments = \xoops_getModuleOption('contact_dept', 'contact');
0 ignored issues
show
Deprecated Code introduced by
The function xoops_getModuleOption() has been deprecated. ( Ignorable by Annotation )

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

276
            $departments = /** @scrutinizer ignore-deprecated */ \xoops_getModuleOption('contact_dept', 'contact');
Loading history...
277
            foreach ($departments as $vals) {
278
                $vale = \explode(',', $vals);
279
                if ($department == $vale[0]) {
280
                    $department_mail[] = $vale[1];
281
                }
282
            }
283
        }
284
285
        return $department_mail;
286
    }
287
288
    /**
289
     * @param $contact_id
290
     * @return bool
291
     */
292
    public function contactAddReply($contact_id): bool
293
    {
294
        $obj = $this->get($contact_id);
295
        $obj->setVar('contact_reply', 1);
296
        if (!$this->insert($obj)) {
297
            return false;
298
        }
299
300
        return true;
301
    }
302
303
    /**
304
     * @param $contact_id
305
     * @return array|bool
306
     */
307
    public function contactGetReply($contact_id)
308
    {
309
        $ret = false;
310
        $tab = [];
311
312
        $criteria = new \CriteriaCompo();
313
        $criteria->add(new \Criteria('contact_cid', $contact_id));
314
        $criteria->add(new \Criteria('contact_type', 'Contact'));
315
        $contacts = &$this->getObjects($criteria, false);
316
        if ($contacts) {
317
            $ret = [];
318
            /** @var Contact $root */
319
            foreach ($contacts as $root) {
320
                $tab                   = $root->toArray();
321
                $tab['contact_owner']  = \XoopsUser::getUnameFromId($root->getVar('contact_uid'));
322
                $tab['contact_create'] = \formatTimestamp($root->getVar('contact_create'), _MEDIUMDATESTRING);
323
                $ret []                = $tab;
324
                unset($tab);
325
            }
326
        }
327
328
        return $ret;
329
    }
330
331
    /**
332
     * @param $contact
333
     * @param $id
334
     * @return array
335
     */
336
    public function contactGetAdminList($contact, $id): array
337
    {
338
        $ret      = [];
339
        $criteria = new \CriteriaCompo();
340
        $criteria->add(new \Criteria($id, '0'));
341
        $criteria->add(new \Criteria('contact_type', 'Contact'));
342
        $criteria->setSort($contact['sort']);
343
        $criteria->setOrder($contact['order']);
344
        $criteria->setStart($contact['start']);
345
        $criteria->setLimit($contact['limit']);
346
        $contacts = &$this->getObjects($criteria, false);
347
        if ($contacts) {
348
            /** @var Contact $root */
349
            foreach ($contacts as $root) {
350
                $tab                   = [];
351
                $tab                   = $root->toArray();
352
                $tab['contact_owner']  = \XoopsUser::getUnameFromId($root->getVar('contact_uid'));
353
                $tab['contact_create'] = \formatTimestamp($root->getVar('contact_create'), _MEDIUMDATESTRING);
354
                $ret []                = $tab;
355
            }
356
        }
357
358
        return $ret;
359
    }
360
361
    /**
362
     * Get file Count
363
     * @param int $id
364
     * @return int|string
365
     */
366
    public function contactGetCount($id)
367
    {
368
        $criteria = new \CriteriaCompo();
369
        $criteria->add(new \Criteria($id, '0'));
370
        $criteria->add(new \Criteria('contact_type', 'Contact'));
371
372
        return $this->getCount($criteria);
373
    }
374
375
    /**
376
     * Get Insert ID
377
     */
378
    public function getInsertId()
379
    {
380
        return $this->db->getInsertId();
381
    }
382
383
    /**
384
     * Contact Prune Count
385
     * @param $timestamp
386
     * @param $onlyreply
387
     * @return int|string
388
     */
389
    public function contactPruneCount($timestamp, $onlyreply)
390
    {
391
        $criteria = new \CriteriaCompo();
392
        $criteria->add(new \Criteria('contact_create', $timestamp, '<='));
393
        if ($onlyreply) {
394
            $criteria->add(new \Criteria('contact_reply', 1));
395
        }
396
397
        return $this->getCount($criteria);
398
    }
399
400
    /**
401
     * Contact Delete Before Date
402
     * @param $timestamp
403
     * @param $onlyreply
404
     */
405
    public function contactDeleteBeforeDate($timestamp, $onlyreply): void
406
    {
407
        $criteria = new \CriteriaCompo();
408
        $criteria->add(new \Criteria('contact_create', $timestamp, '<='));
409
        if ($onlyreply) {
410
            $criteria->add(new \Criteria('contact_reply', 1));
411
        }
412
        $this->deleteAll($criteria);
413
    }
414
415
    /**
416
     * Contact Platform
417
     * @param $platform
418
     * @return string
419
     */
420
    public function contactPlatform($platform): string
421
    {
422
        $platform = \mb_strtolower($platform);
423
        switch ($platform) {
424
            case 'Android':
425
                $ret = 'Android';
426
                break;
427
            case 'Ios':
428
                $ret = 'Ios';
429
                break;
430
            case 'Web':
431
            default:
432
                $ret = 'Web';
433
                break;
434
        }
435
436
        return $ret;
437
    }
438
439
    /**
440
     * Contact type
441
     * @param $type
442
     * @return string
443
     */
444
    public function contactType($type): string
445
    {
446
        $type = \mb_strtolower($type);
447
        switch ($type) {
448
            case 'Mail':
449
                $ret = 'Mail';
450
                break;
451
            case 'Phone':
452
                $ret = 'Phone';
453
                break;
454
            case 'Contact':
455
            default:
456
                $ret = 'Contact';
457
                break;
458
        }
459
460
        return $ret;
461
    }
462
463
    /**
464
     * Contact logs
465
     * @param      $column
466
     * @param null $timestamp
467
     * @return array
468
     */
469
    public function contactLogs($column, $timestamp = null): array
470
    {
471
        $ret = [];
472
        if (!\in_array($column, ['contact_mail', 'contact_url', 'contact_phone'], true)) {
473
            return $ret;
474
        }
475
        $criteria = new \CriteriaCompo();
476
        $criteria->add(new \Criteria('contact_cid', '0'));
477
        if (!empty($timestamp)) {
478
            $criteria->add(new \Criteria('contact_create', $timestamp, '<='));
479
        }
480
        $criteria->setSort('contact_create');
481
        $criteria->setOrder('DESC');
482
        $contacts = &$this->getObjects($criteria, false);
483
        if ($contacts) {
484
            /** @var Contact $root */
485
            foreach ($contacts as $root) {
486
                $rootColumn = $root->getVar($column);
487
                if (!empty($rootColumn)) {
488
                    $ret[] = $root->getVar($column);
489
                    unset($root);
490
                }
491
            }
492
        }
493
494
        return \array_unique($ret);
495
    }
496
}
497