Issues (56)

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.

src/Helper/ValidatorTrait.php (1 issue)

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
declare(strict_types=1);
4
5
namespace Kerox\Messenger\Helper;
6
7
use Kerox\Messenger\Exception\InvalidArrayException;
8
use Kerox\Messenger\Exception\InvalidClassException;
9
use Kerox\Messenger\Exception\InvalidColorException;
10
use Kerox\Messenger\Exception\InvalidCountryException;
11
use Kerox\Messenger\Exception\InvalidCurrencyException;
12
use Kerox\Messenger\Exception\InvalidDateTimeException;
13
use Kerox\Messenger\Exception\InvalidExtensionException;
14
use Kerox\Messenger\Exception\InvalidKeyException;
15
use Kerox\Messenger\Exception\InvalidLocaleException;
16
use Kerox\Messenger\Exception\InvalidStringException;
17
use Kerox\Messenger\Exception\InvalidTypeException;
18
use Kerox\Messenger\Exception\InvalidUrlException;
19
use Kerox\Messenger\Exception\MessengerException;
20
use Kerox\Messenger\Model\Common\Button\AbstractButton;
21
use Kerox\Messenger\Model\Message;
22
use Kerox\Messenger\Model\Message\AbstractAttachment;
23
use Kerox\Messenger\Model\Message\Attachment\Template\GenericTemplate;
24
use Kerox\Messenger\SendInterface;
25
26
trait ValidatorTrait
27
{
28
    /**
29
     * @throws \Kerox\Messenger\Exception\InvalidColorException
30
     */
31 2
    protected function isValidColor(string $value): void
32
    {
33 2
        if (!preg_match('/^#[A-Fa-f0-9]{6}$/', $value)) {
34 1
            throw new InvalidColorException('The color must be expressed in #rrggbb format.');
35
        }
36 1
    }
37
38
    /**
39
     * @throws \Kerox\Messenger\Exception\InvalidStringException
40
     */
41 39
    protected function isValidString(string $value, int $length = 20): void
42
    {
43 39
        if (mb_strlen($value) > $length) {
44 1
            throw new InvalidStringException(sprintf('String should not exceed %s characters.', $length));
45
        }
46 38
    }
47
48
    /**
49
     * @throws \Kerox\Messenger\Exception\InvalidUrlException
50
     */
51 38
    protected function isValidUrl(string $value): void
52
    {
53 38
        if (!preg_match(
54 38
            '/^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&\/=]*)$/',
55
            $value
56
        )) {
57 1
            throw new InvalidUrlException(sprintf('"%s" is not a valid url.', $value));
58
        }
59 37
    }
60
61
    /**
62
     * @throws \Kerox\Messenger\Exception\InvalidLocaleException
63
     */
64 8
    protected function isValidLocale(string $value): void
65
    {
66 8
        if (!preg_match('/^[a-z]{2}_[A-Z]{2}$/', $value)) {
67 1
            throw new InvalidLocaleException(sprintf('"%s" is not valid. Locale must be in ISO-639-1 and ISO-3166-1 format like fr_FR.', $value));
68
        }
69 7
    }
70
71
    /**
72
     * @throws \Kerox\Messenger\Exception\InvalidCountryException
73
     */
74 2
    protected function isValidCountry(string $value): void
75
    {
76 2
        if (!preg_match('/^[A-Z]{2}$/', $value)) {
77 1
            throw new InvalidCountryException(sprintf('"%s" is not valid. Country must be in ISO 3166 Alpha-2 format like FR.', $value));
78
        }
79 1
    }
80
81
    /**
82
     * @throws \Kerox\Messenger\Exception\InvalidDateTimeException
83
     */
84 11
    protected function isValidDateTime(string $value): void
85
    {
86 11
        if (!preg_match('/^(\d{4})-(0[1-9]|1[0-2])-([12]\d|0[1-9]|3[01])T(0\d|1\d|2[0-3]):([0-5]\d)$/', $value)) {
87 1
            throw new InvalidDateTimeException(sprintf('"%s" is not valid. DateTime must be in ISO-8601 AAAA-MM-JJThh:mm format.', $value));
88
        }
89 10
    }
90
91
    /**
92
     * @param int $minSize
93
     *
94
     * @throws \Kerox\Messenger\Exception\InvalidArrayException
95
     */
96 32
    protected function isValidArray(array $array, int $maxSize, ?int $minSize = null): void
97
    {
98 32
        $countArray = \count($array);
99 32
        if ($minSize !== null && $countArray < $minSize) {
100 2
            throw new InvalidArrayException(sprintf('The minimum number of items for this array is %d.', $minSize));
101
        }
102 30
        if ($countArray > $maxSize) {
103 4
            throw new InvalidArrayException(sprintf('The maximum number of items for this array is %d.', $maxSize));
104
        }
105 29
    }
106
107
    /**
108
     * @throws \Kerox\Messenger\Exception\InvalidCurrencyException
109
     */
110 8
    protected function isValidCurrency(string $value): void
111
    {
112 8
        $allowedCurrency = $this->getAllowedCurrency();
113
114 8
        $regex = '/^' . implode('|', $allowedCurrency) . '$/';
115 8
        if (!preg_match($regex, $value)) {
116 1
            throw new InvalidCurrencyException(sprintf('"%s" is not a valid currency. Currency must be in ISO-4217-3 format.', $value));
117
        }
118 7
    }
119
120
    /**
121
     * @throws \Kerox\Messenger\Exception\InvalidExtensionException
122
     */
123 3
    protected function isValidExtension(string $filename, array $allowedExtension): void
124
    {
125 3
        $ext = pathinfo($filename, PATHINFO_EXTENSION);
126 3
        if (empty($ext) || !\in_array($ext, $allowedExtension, true)) {
127 1
            throw new InvalidExtensionException(sprintf('"%s" does not have a valid extension. Allowed extensions are "%s".', $filename, implode(', ', $allowedExtension)));
128
        }
129 2
    }
130
131
    /**
132
     * @param \Kerox\Messenger\Model\Common\Button\AbstractButton[] $buttons
133
     *
134
     * @throws \Kerox\Messenger\Exception\InvalidClassException
135
     */
136 8
    protected function isValidButtons(array $buttons, array $allowedButtonsType): void
137
    {
138
        /** @var \Kerox\Messenger\Model\Common\Button\AbstractButton $button */
139 8
        foreach ($buttons as $button) {
140 8
            if (!$button instanceof AbstractButton) {
141 1
                throw new InvalidClassException(sprintf('Array can only contain instance of "%s".', AbstractButton::class));
142
            }
143
144 7
            if (!\in_array($button->getType(), $allowedButtonsType, true)) {
145 3
                throw new InvalidClassException(sprintf('Buttons can only be an instance of "%s".', implode(', ', $allowedButtonsType)));
146
            }
147
        }
148 5
    }
149
150
    /**
151
     * @param mixed $message
152
     *
153
     * @throws \Exception
154
     */
155 7
    protected function isValidMessage($message): Message
156
    {
157 7
        if ($message instanceof Message) {
158
            return $message;
159
        }
160
161 7
        if (\is_string($message) || $message instanceof AbstractAttachment) {
162 6
            return Message::create($message);
163
        }
164
165 1
        throw new MessengerException(sprintf('"message" must be a string or an instance of "%s" or "%s".', Message::class, AbstractAttachment::class));
166
    }
167
168
    /**
169
     * @throws \Kerox\Messenger\Exception\InvalidKeyException
170
     */
171 2
    protected function isValidSenderAction(string $action): void
172
    {
173 2
        $allowedSenderAction = $this->getAllowedSenderAction();
174 2
        if (!\in_array($action, $allowedSenderAction, true)) {
175 1
            throw new InvalidKeyException(sprintf('"action" must be either "%s".', implode(', ', $allowedSenderAction)));
176
        }
177 1
    }
178
179
    /**
180
     * @throws \Kerox\Messenger\Exception\InvalidTypeException
181
     */
182 5
    protected function isValidNotificationType(string $notificationType): void
183
    {
184 5
        $allowedNotificationType = $this->getAllowedNotificationType();
185 5
        if (!\in_array($notificationType, $allowedNotificationType, true)) {
186 1
            throw new InvalidTypeException(sprintf('"notificationType" must be either "%s".', implode(', ', $allowedNotificationType)));
187
        }
188 4
    }
189
190
    /**
191
     * @param mixed $message
192
     *
193
     * @throws \Kerox\Messenger\Exception\InvalidClassException
194
     * @throws \Kerox\Messenger\Exception\InvalidKeyException
195
     */
196 3
    protected function isValidTag(string $tag, $message = null): void
197
    {
198 3
        $allowedTag = $this->getAllowedTag();
199 3
        $deprecatedTag = $this->getDeprecatedTags();
200 3
        if (!\in_array($tag, $allowedTag, true)) {
201 1
            throw new InvalidKeyException(sprintf('"tag" must be either "%s".', implode(', ', $allowedTag)));
202
        }
203
204 2
        if (\in_array($tag, $deprecatedTag, true)) {
205 1
            $message = sprintf('Tag "%s" is deprecated, use one of "%s" instead.',
206
                $tag,
207 1
                implode(',', [
208 1
                    SendInterface::TAG_CONFIRMED_EVENT_UPDATE,
209 1
                    SendInterface::TAG_POST_PURCHASE_UPDATE,
210 1
                    SendInterface::TAG_ACCOUNT_UPDATE,
211
                ])
212
            );
213 1
            @trigger_error($message, E_USER_DEPRECATED);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
214
        }
215
216 2
        if ($tag === SendInterface::TAG_ISSUE_RESOLUTION && $message !== null && !$message instanceof GenericTemplate) {
217 1
            throw new InvalidClassException(sprintf('"message" must be an instance of "%s" if tag is set to "%s".', GenericTemplate::class, SendInterface::TAG_ISSUE_RESOLUTION));
218
        }
219 1
    }
220
221 2
    protected function getAllowedSenderAction(): array
222
    {
223
        return [
224 2
            SendInterface::SENDER_ACTION_TYPING_ON,
225 2
            SendInterface::SENDER_ACTION_TYPING_OFF,
226 2
            SendInterface::SENDER_ACTION_MARK_SEEN,
227
        ];
228
    }
229
230 5
    protected function getAllowedNotificationType(): array
231
    {
232
        return [
233 5
            SendInterface::NOTIFICATION_TYPE_REGULAR,
234 5
            SendInterface::NOTIFICATION_TYPE_SILENT_PUSH,
235 5
            SendInterface::NOTIFICATION_TYPE_NO_PUSH,
236
        ];
237
    }
238
239 3
    protected function getAllowedTag(): array
240
    {
241
        return [
242 3
            SendInterface::TAG_CONFIRMED_EVENT_UPDATE,
243 3
            SendInterface::TAG_POST_PURCHASE_UPDATE,
244 3
            SendInterface::TAG_ACCOUNT_UPDATE,
245
            //Tags supported until March 4th, 2020.
246 3
            SendInterface::TAG_BUSINESS_PRODUCTIVITY,
247 3
            SendInterface::TAG_COMMUNITY_ALERT,
248 3
            SendInterface::TAG_CONFIRMED_EVENT_REMINDER,
249 3
            SendInterface::TAG_NON_PROMOTIONAL_SUBSCRIPTION,
250 3
            SendInterface::TAG_PAIRING_UPDATE,
251 3
            SendInterface::TAG_APPLICATION_UPDATE,
252 3
            SendInterface::TAG_PAYMENT_UPDATE,
253 3
            SendInterface::TAG_PERSONAL_FINANCE_UPDATE,
254 3
            SendInterface::TAG_SHIPPING_UPDATE,
255 3
            SendInterface::TAG_RESERVATION_UPDATE,
256 3
            SendInterface::TAG_ISSUE_RESOLUTION,
257 3
            SendInterface::TAG_APPOINTMENT_UPDATE,
258 3
            SendInterface::TAG_GAME_EVENT,
259 3
            SendInterface::TAG_TRANSPORTATION_UPDATE,
260 3
            SendInterface::TAG_FEATURE_FUNCTIONALITY_UPDATE,
261 3
            SendInterface::TAG_TICKET_UPDATE,
262
        ];
263
    }
264
265 3
    protected function getDeprecatedTags(): array
266
    {
267
        return [
268 3
            SendInterface::TAG_BUSINESS_PRODUCTIVITY,
269 3
            SendInterface::TAG_COMMUNITY_ALERT,
270 3
            SendInterface::TAG_CONFIRMED_EVENT_REMINDER,
271 3
            SendInterface::TAG_NON_PROMOTIONAL_SUBSCRIPTION,
272 3
            SendInterface::TAG_PAIRING_UPDATE,
273 3
            SendInterface::TAG_APPLICATION_UPDATE,
274 3
            SendInterface::TAG_PAYMENT_UPDATE,
275 3
            SendInterface::TAG_PERSONAL_FINANCE_UPDATE,
276 3
            SendInterface::TAG_SHIPPING_UPDATE,
277 3
            SendInterface::TAG_RESERVATION_UPDATE,
278 3
            SendInterface::TAG_ISSUE_RESOLUTION,
279 3
            SendInterface::TAG_APPOINTMENT_UPDATE,
280 3
            SendInterface::TAG_GAME_EVENT,
281 3
            SendInterface::TAG_TRANSPORTATION_UPDATE,
282 3
            SendInterface::TAG_FEATURE_FUNCTIONALITY_UPDATE,
283 3
            SendInterface::TAG_TICKET_UPDATE,
284
        ];
285
    }
286
287 8
    protected function getAllowedCurrency(): array
288
    {
289
        return [
290 8
            'SGD',
291
            'RON',
292
            'EUR',
293
            'TRY',
294
            'SEK',
295
            'ZAR',
296
            'HKD',
297
            'CHF',
298
            'NIO',
299
            'JPY',
300
            'ISK',
301
            'TWD',
302
            'NZD',
303
            'CZK',
304
            'AUD',
305
            'THB',
306
            'BOB',
307
            'BRL',
308
            'MXN',
309
            'USD',
310
            'ILS',
311
            'HNL',
312
            'MOP',
313
            'COP',
314
            'UYU',
315
            'CRC',
316
            'DKK',
317
            'QAR',
318
            'PYG',
319
            'CAD',
320
            'INR',
321
            'KRW',
322
            'GTQ',
323
            'AED',
324
            'VEF',
325
            'SAR',
326
            'NOK',
327
            'CNY',
328
            'ARS',
329
            'PLN',
330
            'GBP',
331
            'PEN',
332
            'PHP',
333
            'VND',
334
            'RUB',
335
            'HUF',
336
            'MYR',
337
            'CLP',
338
            'IDR',
339
        ];
340
    }
341
}
342