Issues (50)

Security Analysis    no request data  

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.

transports/mail/Mailer.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 namespace nyx\notify\transports\mail;
2
3
/**
4
 * Mailer
5
 *
6
 * @package     Nyx\Notify
7
 * @version     0.1.0
8
 * @author      Michal Chojnacki <[email protected]>
9
 * @copyright   2012-2017 Nyx Dev Team
10
 * @link        https://github.com/unyx/nyx
11
 */
12
class Mailer implements interfaces\Mailer
13
{
14
    /**
15
     * @var interfaces\Driver   The Driver used to actually send Messages.
16
     */
17
    protected $driver;
18
19
    /**
20
     * @var \Illuminate\Contracts\View\Factory  The View Factory responsible for creating the requested views.
21
     */
22
    protected $viewFactory;
23
24
    /**
25
     * @var array   An array of (optional) 'always to' and 'always from' addresses to simplify the creation and testing
26
     *              of Messages.
27
     */
28
    protected $always = [];
29
30
    /**
31
     * @var int     The maximum number of retries allowed to make upon driver connection failures.
32
     */
33
    protected $allowedRetries = 5;
34
35
    /**
36
     * @var int     The current number of connection retries made.
37
     */
38
    protected $currentRetries = 0;
39
40
    /**
41
     * Constructs a new Mailer instance.
42
     *
43
     * @param   interfaces\Driver                   $driver         The Driver to use to actually send Messages.
44
     * @param   \Illuminate\Contracts\View\Factory  $viewFactory    The View Factory responsible for creating the requested views.
45
     */
46
    public function __construct(interfaces\Driver $driver, \Illuminate\Contracts\View\Factory $viewFactory)
47
    {
48
        $this->driver      = $driver;
49
        $this->viewFactory = $viewFactory;
50
    }
51
52
    /**
53
     * Sets the "always from" message header, which is used to populate the "from" field on Messages that do not yet
54
     * have a sender set.
55
     *
56
     * @param   string|array    $address
57
     * @return  $this
58
     */
59
    public function setAlwaysFrom($address) : Mailer
60
    {
61
        $this->always['from'] = $address;
62
63
        return $this;
64
    }
65
66
    /**
67
     * Sets the "always to" message header, which is used to populate the "to" field on *all* outgoing Messages,
68
     * regardless if they already have any recipients set.
69
     *
70
     * This functionality is primarily intended for testing purposes.
71
     *
72
     * @param   string|array    $address
73
     * @return  $this
74
     */
75
    public function setAlwaysTo($address)
76
    {
77
        $this->always['to'] = $address;
78
79
        return $this;
80
    }
81
82
    /**
83
     * {@inheritDoc}
84
     */
85
    public function send($view, array $data = null, callable $builder = null, array &$failures = null) : int
86
    {
87
        if ($view instanceof Message) {
88
            $message = $view;
89
        } else {
90
            $message = $this->createMessage($view);
91
        }
92
93
        // Pass the view data to the Message, if it was given.
94
        if (isset($data)) {
95
            $message->with($data);
96
        }
97
98
        // Render the views and associate the resulting output as the body and parts of the outgoing Message.
99
        $this->buildEntities($message);
100
101
        // Set the "always from" header field but only if no sender is already set. Opposed to "always to",
102
        // the "always from" field does not override existing headers.
103
        if (isset($this->always['from']) && empty($message->getFrom())) {
104
            $message->setFrom($this->always['from']);
105
        }
106
107
        if (isset($builder)) {
108
            return call_user_func($builder, $message);
109
        }
110
111
        // The "always to" header field overrides any recipients set on outgoing Messages, if it's configured.
112
        if (isset($this->always['to'])) {
113
            $message->setTo($this->always['to']);
114
        }
115
116
        return $this->doSend($message, $failures);
117
    }
118
119
    /**
120
     * Performs the actual sending of a MIME Message using the configured Driver.
121
     *
122
     * @param   \Swift_Mime_Message $message    The Message to send.
123
     * @param   array               &$failures  A reference to an array which will hold data about all requested
124
     *                                          recipients sending to whom failed.
125
     * @return  int                             The number of recipients the Message has been sent to.
126
     */
127
    protected function doSend(\Swift_Mime_Message $message, array &$failures = null) : int
128
    {
129
        try {
130
131
            if ($this->driver instanceof interfaces\drivers\Process && !$this->driver->isStarted()) {
132
                $this->driver->start();
133
            }
134
135
            $count = $this->driver->send($message, $failures);
136
137
            // Reset the retry counter on successful requests.
138
            $this->currentRetries = 0;
139
140
            return $count;
141
142
        } catch (\Swift_RfcComplianceException $exception) {
143
144
            if (isset($failures)) {
145
                foreach ($message->getTo() as $address => $name) {
146
                    $failures[] = $address;
147
                }
148
            }
149
150
        } catch (\Swift_TransportException $exception) {
151
            return $this->handleTransportException($message, $exception, $failures);
152
        }
153
    }
154
155
    /**
156
     * Attempts to recover from a Driver Exception by retrying delivery, restarting the Driver's Process if need be,
157
     * unless the maximum number of allowed retries has been exceeded.
158
     *
159
     * @param   \Swift_Mime_Message         $message    The Message we are trying to send.
160
     * @param   \Swift_TransportException   $exception  The Exception we are attempting to recover from.
161
     * @param   array                       &$failures  A reference to an array which will hold data about all requested
162
     *                                                  recipients sending to whom failed.
163
     * @return  int                                     The number of recipients the Message has been sent to.
164
     * @throws  \RuntimeException                       When recovery was impossible due to exceeding the maximum number
165
     *                                                  of allowed retries.
166
     */
167
    protected function handleTransportException(\Swift_Mime_Message $message, \Swift_TransportException $exception, array &$failures = null) : int
0 ignored issues
show
The parameter $exception is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
168
    {
169
        // Prevent further re-tries if we're at or above our threshold.
170
        if ($this->currentRetries >= $this->allowedRetries) {
171
            throw new \RuntimeException('The mail transport connection failed. Retried connecting '.$this->currentRetries.' time(s).');
172
        }
173
174
        // Transport exceptions in case of Process drivers may just be temporary, so we'll try to re-establish
175
        // the process (connection) from scratch in those cases.
176
        if ($this->driver instanceof interfaces\drivers\Process) {
177
            $this->driver->stop();
178
        }
179
180
        $this->currentRetries++;
181
182
        // Try again.
183
        return $this->doSend($message, $failures);
184
    }
185
186
    /**
187
     * Renders a Message's views and associates the resulting output as the body
188
     * and respective MIME parts of the Message.
189
     *
190
     * @param   Message $message    The Message whose MIME entities should be set.
191
     */
192
    protected function buildEntities(Message $message)
193
    {
194
        list($view, $plain, $raw) = $this->determineViews($message->getViews());
195
196
        $data = $message->getViewData();
197
198
        if (isset($view)) {
199
            $message->setBody($this->viewFactory->make($view, $data)->render(), 'text/html');
200
        }
201
202
        if (isset($plain)) {
203
            $method = isset($view) ? 'addPart' : 'setBody';
204
205
            $message->$method($this->viewFactory->make($plain, $data)->render(), 'text/plain');
206
        }
207
208
        if (isset($raw)) {
209
            $method = (isset($view) || isset($plain)) ? 'addPart' : 'setBody';
210
211
            $message->$method($raw, 'text/plain');
212
        }
213
    }
214
215
    /**
216
     * Determines what type of views (html, text or raw) are specified in the given $view value.
217
     *
218
     * @param   string|array    $view       The value to base on.
219
     * @return  array                       A numerically indexed array with the respective view names corresponding to:
220
     *                                      0 => html, 1 => text, 2 => raw view names.
221
     * @throws  \InvalidArgumentException   If the given value is neither a string nor an array.
222
     */
223
    protected function determineViews($view) : array
224
    {
225
        if (is_string($view)) {
226
            return [$view];
227
        }
228
229
        if (is_array($view)) {
230
231
            if (isset($view[0])) {
232
                return [$view[0], $view[1]];
233
            }
234
235
            return [
236
                $view['html'] ?? null,
237
                $view['text'] ?? null,
238
                $view['raw']  ?? null,
239
            ];
240
        }
241
242
        throw new \InvalidArgumentException('Unrecognized view format given - unable to determine which views to render.');
243
    }
244
245
    /**
246
     * Creates a new Mail Message.
247
     *
248
     * @param   string|array    $view   The view(s) to associate the Message with.
249
     * @return  Message
250
     */
251
    protected function createMessage($view) : Message
252
    {
253
        return new Message((array) $view);
254
    }
255
}
256